From 6cb5096087bb287b58f2fd0ae54325f0b45707e5 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 28 Aug 2014 17:08:48 -0700 Subject: [PATCH 01/34] Make getCurrentDirectory and getDefaultLibFilename invocation in management side --- src/services/services.ts | 80 +++++++++++++++++++++++++++++++++++----- src/services/shims.ts | 9 +++++ 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 0069f53922d..e33de3b172d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -417,6 +417,8 @@ module ts { getScriptSnapshot(fileName: string): TypeScript.IScriptSnapshot; getLocalizedDiagnosticMessages(): any; getCancellationToken(): CancellationToken; + getDefaultLibFilename(): string; + getCurrentDirectory(): string; } // @@ -683,8 +685,6 @@ module ts { name: string; writeByteOrderMark: boolean; text: string; - fileType: OutputFileType; - sourceMapOutput: any; } export enum EndOfLineState { @@ -1393,6 +1393,7 @@ module ts { var documentRegistry = documentRegistry; var cancellationToken = new CancellationTokenObject(host.getCancellationToken()); var activeCompletionSession: CompletionSession; // The current active completion session, used to get the completion entry details + var writter: (filename: string, data: string, writebyteordermark: boolean) => void = undefined; // Check if the localized messages json is set, otherwise query the host for it if (!TypeScript.LocalizedDiagnosticMessages) { @@ -1419,13 +1420,17 @@ module ts { getNewLine: () => "\r\n", // Need something that doesn't depend on sys.ts here getDefaultLibFilename: (): string => { - throw Error("TOD:: getDefaultLibfilename"); + return host.getDefaultLibFilename(); }, writeFile: (filename, data, writeByteOrderMark) => { - throw Error("TODO: write file"); + if (writter) { + writter(filename, data, writeByteOrderMark); + return; + } + throw Error("Error occurs: Invalid invocation to writeFile"); }, getCurrentDirectory: (): string => { - throw Error("TODO: getCurrentDirectory"); + return host.getCurrentDirectory(); } }; } @@ -2319,7 +2324,7 @@ module ts { return getReferencesForNode(node, program.getSourceFiles()); } - function getReferencesForNode(node: Node, sourceFiles : SourceFile[]): ReferenceEntry[] { + function getReferencesForNode(node: Node, sourceFiles: SourceFile[]): ReferenceEntry[] { // Labels if (isLabelName(node)) { if (isJumpStatementTarget(node)) { @@ -2354,8 +2359,9 @@ module ts { var searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), symbol.getDeclarations()); // Get the text to search for, we need to normalize it as external module names will have quote - var symbolName = getNormalizedSymbolName(symbol); + var symbolName = getNormalizedSymbolName(symbol); + // Get syntactic diagnostics var scope = getSymbolScope(symbol); if (scope) { @@ -2385,7 +2391,7 @@ module ts { else { var name = symbol.name; } - + var length = name.length; if (length >= 2 && name.charCodeAt(0) === CharacterCodes.doubleQuote && name.charCodeAt(length - 1) === CharacterCodes.doubleQuote) { return name.substring(1, length - 1); @@ -2658,7 +2664,7 @@ module ts { if (node.kind === SyntaxKind.StringLiteral) { start += 1; end -= 1; - } + } return new ReferenceEntry(node.getSourceFile().filename, TypeScript.TextSpan.fromBounds(start, end), isWriteAccess(node)); } @@ -2834,6 +2840,60 @@ module ts { } } } + function containErrors(diagnostics: Diagnostic[]): boolean { + var hasError = forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); + return hasError; + } + + function getEmitOutput(filename: string): EmitOutput { + synchronizeHostData(); + filename = TypeScript.switchToForwardSlashes(filename); + var emitToSingleFile = program.getCompilerOptions().out; + var emitDeclaration = program.getCompilerOptions().declaration; + var emitResult: EmitOutput = { + outputFiles: [], + emitOutputResult: null, + }; + + // Initialize writter for CompilerHost.writeFile + writter = function (fileName: string, data: string, writeByteOrderMark: boolean) { + var outputFile: OutputFile = { + name: fileName, + writeByteOrderMark: writeByteOrderMark, + text: data + } + + emitResult.outputFiles.push(outputFile); + } + + // Get syntactic diagnostics + var syntacticDiagnostics = emitToSingleFile + ? program.getDiagnostics(getSourceFile(filename).getSourceFile()) + : program.getDiagnostics(); + program.getGlobalDiagnostics(); + + if (containErrors(syntacticDiagnostics)) { + emitResult.emitOutputResult = EmitOutputResult.FailedBecauseOfSyntaxErrors; + return emitResult; + } + + // Perform semantic and forace a type check before emit to ensure that all symbols are updated + var semanticDiagnostics = emitToSingleFile + ? getFullTypeCheckChecker().getDiagnostics(getSourceFile(filename).getSourceFile()) + : getFullTypeCheckChecker().getDiagnostics(); + getFullTypeCheckChecker().getGlobalDiagnostics(); + getFullTypeCheckChecker().emitFiles(); + + if (emitDeclaration && containErrors(semanticDiagnostics)) { + emitResult.emitOutputResult = EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors; + } + else { + emitResult.emitOutputResult = EmitOutputResult.Succeeded; + } + + // Reset writter back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in an emitting stage + return null; + } /// Syntactic features function getSyntaxTree(filename: string): TypeScript.SyntaxTree { @@ -3185,7 +3245,7 @@ module ts { getFormattingEditsForRange: getFormattingEditsForRange, getFormattingEditsForDocument: getFormattingEditsForDocument, getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke, - getEmitOutput: (filename): EmitOutput => null, + getEmitOutput: getEmitOutput, }; } diff --git a/src/services/shims.ts b/src/services/shims.ts index 0659f9f2512..2e19db2815a 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -53,6 +53,8 @@ module ts { getScriptSnapshot(fileName: string): ScriptSnapshotShim; getLocalizedDiagnosticMessages(): string; getCancellationToken(): CancellationToken; + getDefaultLibFilename(): string; + getCurrentDirectory(): string; } // @@ -362,6 +364,13 @@ module ts { public getCancellationToken(): CancellationToken { return this.shimHost.getCancellationToken(); } + + getDefaultLibFilename(): string { + return this.shimHost.getDefaultLibFilename(); + } + getCurrentDirectory(): string { + return this.shimHost.getCurrentDirectory(); + } } function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any): any { From da1becccf70ec4a53d4fed9574e07dd529e0512c Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 3 Sep 2014 09:29:33 -0700 Subject: [PATCH 02/34] Add old test files that use getEmitOutput --- tests/cases/{fourslash_old => fourslash}/eval.ts | 0 tests/cases/{fourslash_old => fourslash}/moduleReferenceValue.ts | 0 tests/cases/{fourslash_old => fourslash}/runtimeBehaviorTests.ts | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename tests/cases/{fourslash_old => fourslash}/eval.ts (100%) rename tests/cases/{fourslash_old => fourslash}/moduleReferenceValue.ts (100%) rename tests/cases/{fourslash_old => fourslash}/runtimeBehaviorTests.ts (100%) diff --git a/tests/cases/fourslash_old/eval.ts b/tests/cases/fourslash/eval.ts similarity index 100% rename from tests/cases/fourslash_old/eval.ts rename to tests/cases/fourslash/eval.ts diff --git a/tests/cases/fourslash_old/moduleReferenceValue.ts b/tests/cases/fourslash/moduleReferenceValue.ts similarity index 100% rename from tests/cases/fourslash_old/moduleReferenceValue.ts rename to tests/cases/fourslash/moduleReferenceValue.ts diff --git a/tests/cases/fourslash_old/runtimeBehaviorTests.ts b/tests/cases/fourslash/runtimeBehaviorTests.ts similarity index 100% rename from tests/cases/fourslash_old/runtimeBehaviorTests.ts rename to tests/cases/fourslash/runtimeBehaviorTests.ts From d52fe20df3d77f77be1079bd68e1221cd54cad2f Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 3 Sep 2014 11:07:03 -0700 Subject: [PATCH 03/34] Add getEmitOutput and update call to getCurrentDirectory --- src/compiler/core.ts | 13 +++++++------ src/compiler/emitter.ts | 8 ++++---- src/compiler/parser.ts | 2 +- src/services/services.ts | 15 +++++++++------ 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index fbf767b91a9..7bc9c7e16b2 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -383,11 +383,12 @@ module ts { return [path.substr(0, rootLength)].concat(normalizedParts); } - export function getNormalizedPathComponents(path: string, currentDirectory: string) { + export function getNormalizedPathComponents(path: string, getCurrentDirectory: ()=>string) { var path = normalizeSlashes(path); var rootLength = getRootLength(path); if (rootLength == 0) { // If the path is not rooted it is relative to current directory + var currentDirectory = getCurrentDirectory(); path = combinePaths(normalizeSlashes(currentDirectory), path); rootLength = getRootLength(path); } @@ -443,18 +444,18 @@ module ts { } } - function getNormalizedPathOrUrlComponents(pathOrUrl: string, currentDirectory: string) { + function getNormalizedPathOrUrlComponents(pathOrUrl: string, getCurrentDirectory: ()=>string) { if (isUrl(pathOrUrl)) { return getNormalizedPathComponentsOfUrl(pathOrUrl); } else { - return getNormalizedPathComponents(pathOrUrl, currentDirectory); + return getNormalizedPathComponents(pathOrUrl, getCurrentDirectory); } } - export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, isAbsolutePathAnUrl: boolean) { - var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory); - var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory); + export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, getCurrentDirectory: () => string, isAbsolutePathAnUrl: boolean) { + var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, getCurrentDirectory); + var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, getCurrentDirectory); if (directoryComponents.length > 1 && directoryComponents[directoryComponents.length - 1] === "") { // If the directory path given was of type test/cases/ then we really need components of directry to be only till its name // that is ["test", "cases", ""] needs to be actually ["test", "cases"] diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6b18ad4c133..f8b64dafbce 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -34,7 +34,7 @@ module ts { var newLine = program.getCompilerHost().getNewLine(); function getSourceFilePathInNewDir(newDirPath: string, sourceFile: SourceFile) { - var sourceFilePath = getNormalizedPathFromPathCompoments(getNormalizedPathComponents(sourceFile.filename, compilerHost.getCurrentDirectory())); + var sourceFilePath = getNormalizedPathFromPathCompoments(getNormalizedPathComponents(sourceFile.filename, compilerHost.getCurrentDirectory)); sourceFilePath = sourceFilePath.replace(program.getCommonSourceDirectory(), ""); return combinePaths(newDirPath, sourceFilePath); } @@ -523,7 +523,7 @@ module ts { sourceMapData.sourceMapSources.push(getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, node.filename, - compilerHost.getCurrentDirectory(), + compilerHost.getCurrentDirectory, /*isAbsolutePathAnUrl*/ true)); sourceMapSourceIndex = sourceMapData.sourceMapSources.length - 1; @@ -640,7 +640,7 @@ module ts { sourceMapData.jsSourceMappingURL = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizePath(jsFilePath)), // get the relative sourceMapDir path based on jsFilePath combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap - compilerHost.getCurrentDirectory(), + compilerHost.getCurrentDirectory, /*isAbsolutePathAnUrl*/ true); } else { @@ -3089,7 +3089,7 @@ module ts { declFileName = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizeSlashes(jsFilePath)), declFileName, - compilerHost.getCurrentDirectory(), + compilerHost.getCurrentDirectory, /*isAbsolutePathAnUrl*/ false); referencePathsOutput += "/// " + newLine; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 68c076367d4..64ac4683267 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3817,7 +3817,7 @@ module ts { // Each file contributes into common source file path if (!(sourceFile.flags & NodeFlags.DeclarationFile) && !fileExtensionIs(sourceFile.filename, ".js")) { - var sourcePathCompoments = getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory()); + var sourcePathCompoments = getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory); sourcePathCompoments.pop(); // FileName is not part of directory if (commonPathComponents) { for (var i = 0; i < Math.min(commonPathComponents.length, sourcePathCompoments.length); i++) { diff --git a/src/services/services.ts b/src/services/services.ts index e33de3b172d..5be6e29ff6f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2852,7 +2852,7 @@ module ts { var emitDeclaration = program.getCompilerOptions().declaration; var emitResult: EmitOutput = { outputFiles: [], - emitOutputResult: null, + emitOutputResult: undefined, }; // Initialize writter for CompilerHost.writeFile @@ -2862,37 +2862,40 @@ module ts { writeByteOrderMark: writeByteOrderMark, text: data } - emitResult.outputFiles.push(outputFile); } - // Get syntactic diagnostics var syntacticDiagnostics = emitToSingleFile ? program.getDiagnostics(getSourceFile(filename).getSourceFile()) : program.getDiagnostics(); program.getGlobalDiagnostics(); + // If there is any syntactic error, terminate the process if (containErrors(syntacticDiagnostics)) { emitResult.emitOutputResult = EmitOutputResult.FailedBecauseOfSyntaxErrors; return emitResult; } - // Perform semantic and forace a type check before emit to ensure that all symbols are updated + // Perform semantic and force a type check before emit to ensure that all symbols are updated var semanticDiagnostics = emitToSingleFile ? getFullTypeCheckChecker().getDiagnostics(getSourceFile(filename).getSourceFile()) : getFullTypeCheckChecker().getDiagnostics(); getFullTypeCheckChecker().getGlobalDiagnostics(); - getFullTypeCheckChecker().emitFiles(); + var emitOutput = getFullTypeCheckChecker().emitFiles(); if (emitDeclaration && containErrors(semanticDiagnostics)) { emitResult.emitOutputResult = EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors; } + else if (emitDeclaration && containErrors(emitOutput.errors)) { + emitResult.emitOutputResult = EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors; + } else { emitResult.emitOutputResult = EmitOutputResult.Succeeded; } // Reset writter back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in an emitting stage - return null; + this.writter = undefined; + return emitResult; } /// Syntactic features From 8e37730d859e3ecb5800367fbb6ea241ca7f1eeb Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 3 Sep 2014 11:28:55 -0700 Subject: [PATCH 04/34] Update fourslash for getEmitOutput --- src/harness/fourslash.ts | 51 +++++++++++++++++++++++++++ src/harness/harnessLanguageService.ts | 18 +++++++++- src/harness/projectsRunner.ts | 2 +- tests/cases/fourslash/fourslash.ts | 29 +++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c571a7d9f94..01637a7e822 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -189,6 +189,15 @@ module FourSlash { // Whether or not we should format on keystrokes public enableFormatting = true; + // Whether or not to generate .d.ts file + public enableDeclaration = false; + + // Whether or not to generate one output javascript file + public enableSingleOutputFile = false; + + // Output filename for single-output-file option + public singleOutputFilename: string = undefined; + public formatCodeOptions: ts.FormatCodeOptions; public cancellationToken: TestCancellationToken; @@ -452,6 +461,48 @@ module FourSlash { } } + public verifyEmitOutput(state: ts.EmitOutputResult, filename?: string) { + if (this.enableDeclaration) { + this.languageServiceShimHost.setCompilationSettings({generateDeclarationFiles: true}); + } + + if (this.enableSingleOutputFile) { + this.languageServiceShimHost.setCompilationSettings({ outFileOption: this.singleOutputFilename }); + } + + var expectedFilenames:string[] = []; + if (filename !== undefined) { + expectedFilenames = filename.split(" "); + } + + var emit = this.languageService.getEmitOutput(this.activeFile.fileName); + + if (emit.emitOutputResult !== state) { + throw new Error("Expected emitOutputResult '" + state + "', but actual emitOutputResult '" + emit.emitOutputResult + "'"); + } + + var passed = true; + if (emit.outputFiles.length > 0) { + passed = expectedFilenames.every(expectedFilename => { + return emit.outputFiles.some(outputFile => { + return outputFile.name === expectedFilename; + }); + }); + } + + if (!passed) { + var errorMessage = "Expected outputFilename '" + filename + "', but actualy outputFilename '"; + emit.outputFiles.forEach((outputFile, idx, array) => { + errorMessage += outputFile.name; + if (idx !== emit.outputFiles.length - 1) { + errorMessage += " "; + } + }); + errorMessage += "'"; + throw new Error(errorMessage); + } + } + public verifyMemberListContains(symbol: string, type?: string, docComment?: string, fullSymbolName?: string, kind?: string) { this.scenarioActions.push(''); this.scenarioActions.push(''); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 1a02157d729..e15063204ca 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -135,6 +135,8 @@ module Harness.LanguageService { private fileNameToScript: ts.Map = {}; + private settings: any = {}; + constructor(private cancellationToken: ts.CancellationToken = CancellationToken.None) { } @@ -179,6 +181,14 @@ module Harness.LanguageService { throw new Error("No script with name '" + fileName + "'"); } + public getDefaultLibFilename(): string { + return undefined; + } + + public getCurrentDirectory(): string { + return undefined; + } + ////////////////////////////////////////////////////////////////////// // ILogger implementation // @@ -199,7 +209,7 @@ module Harness.LanguageService { /// Returns json for Tools.CompilationSettings public getCompilationSettings(): string { - return JSON.stringify({}); // i.e. default settings + return JSON.stringify(this.settings); } public getCancellationToken(): ts.CancellationToken { @@ -236,6 +246,12 @@ module Harness.LanguageService { return this.ls; } + public setCompilationSettings(settings: any) { + for (var key in settings) { + this.settings[key] = settings[key]; + } + } + /** Return a new instance of the classifier service shim */ public getClassifier(): ts.ClassifierShim { return new TypeScript.Services.TypeScriptServicesFactory().createClassifierShim(this); diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index b0f3e939d30..7a5fa51e147 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -226,7 +226,7 @@ class ProjectRunner extends RunnerBase { ? filename : ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(filename); - var diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName, getCurrentDirectory(), false); + var diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName, getCurrentDirectory, false); if (ts.isRootedDiskPath(diskRelativeName) || diskRelativeName.substr(0, 3) === "../") { // If the generated output file recides in the parent folder or is rooted path, // we need to instead create files that can live in the project reference folder diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b4080d12e2f..91bce54525a 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -44,6 +44,14 @@ enum TypingFidelity { High = FourSlash.TypingFidelity.High } +// We have to duplicate EmitOutputResult from Services.ts to expose the enum to getEmitOutput testcases in fourslah +enum EmitOutputResult { + Succeeded, + FailedBecauseOfSyntaxErrors, + FailedBecauseOfCompilerOptionsErrors, + FailedToGenerateDeclarationsBecauseOfSemanticErrors +} + module FourSlashInterface { declare var FourSlash; @@ -255,6 +263,10 @@ module FourSlashInterface { FourSlash.currentTestState.verifyEval(expr, value); } + public emitOutput(expectedState: EmitOutputResult, expectedFilename?: string) { + FourSlash.currentTestState.verifyEmitOutput(expectedState, expectedFilename); + } + public currentLineContentIs(text: string) { FourSlash.currentTestState.verifyCurrentLineContent(text); } @@ -431,6 +443,23 @@ module FourSlashInterface { public disableFormatting() { FourSlash.currentTestState.enableFormatting = false; } + + public enableDeclaration() { + FourSlash.currentTestState.enableDeclaration = true; + } + + public disableDeclaration() { + FourSlash.currentTestState.enableDeclaration = false; + } + + public enableSingleOutputFile(outputFilename: string) { + FourSlash.currentTestState.enableSingleOutputFile = true; + FourSlash.currentTestState.singleOutputFilename = outputFilename; + } + + public disableSingleOutputFile() { + FourSlash.currentTestState.enableSingleOutputFile = false; + } } export class debug { From bfc93d4070844b1ade7475fda5e30f599e7d5362 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 3 Sep 2014 11:35:21 -0700 Subject: [PATCH 05/34] Add getEmitOutput test files --- .../getEmitOutputDeclarationMultiFiles.ts | 21 +++++++++++++++++ .../getEmitOutputDeclarationSingleFile.ts | 23 +++++++++++++++++++ .../cases/fourslash/getEmitOutputNoErrors.ts | 10 ++++++++ .../fourslash/getEmitOutputSingleFile.ts | 19 +++++++++++++++ .../getEmitOutputWithSemanticErrors.ts | 7 ++++++ .../getEmitOutputWithSemanticErrors2.ts | 8 +++++++ .../getEmitOutputWithSyntaxErrors.ts | 6 +++++ .../getEmitOutputWithSyntaxErrors2.ts | 10 ++++++++ 8 files changed, 104 insertions(+) create mode 100644 tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts create mode 100644 tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts create mode 100644 tests/cases/fourslash/getEmitOutputNoErrors.ts create mode 100644 tests/cases/fourslash/getEmitOutputSingleFile.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts diff --git a/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts b/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts new file mode 100644 index 00000000000..f2d7724e41b --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts @@ -0,0 +1,21 @@ +/// + +// @Filename: inputFile1.ts +//// var x: number = 5; +//// class Bar { +//// x : string; +//// y : number +//// } + +// @Filename: inputFile2.ts +//// var x1: string = "hello world"; +//// class Foo{ +//// x : string; +//// y : number; +//// } + +var inputFile1 = "tests/cases/fourslash/inputFile1"; +var inputFile2 = "tests/cases/fourslash/inputFile2"; +edit.enableDeclaration(); +var outputFilenames = inputFile1 + ".js" + " " + inputFile2 + ".js" + " " + inputFile1 + ".d.ts" + " " + inputFile2 + ".d.ts"; +verify.emitOutput(EmitOutputResult.Succeeded, outputFilenames); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts b/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts new file mode 100644 index 00000000000..7366640650f --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: inputFile1.ts +//// var x: number = 5; +//// class Bar { +//// x : string; +//// y : number +//// } + +// @Filename: inputFile2.ts +//// var x1: string = "hello world"; +//// class Foo{ +//// x : string; +//// y : number; +//// } + +var singleFilename = "tests/cases/fourslash/declSingleFile"; +var jsFilename = singleFilename + ".js"; +var declFilename = singleFilename + ".d.ts"; +edit.enableSingleOutputFile(jsFilename); +edit.enableDeclaration(); +var outputFilenames = jsFilename + " " + declFilename; +verify.emitOutput(EmitOutputResult.Succeeded, outputFilenames); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputNoErrors.ts b/tests/cases/fourslash/getEmitOutputNoErrors.ts new file mode 100644 index 00000000000..b3cdbc6c469 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputNoErrors.ts @@ -0,0 +1,10 @@ +/// + +// @Filename: noErrorsResult.ts +//// var x; +//// class M { +//// x: number; +//// y: string; +//// } + +verify.emitOutput(EmitOutputResult.Succeeded, "tests/cases/fourslash/noErrorsResult.js"); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSingleFile.ts b/tests/cases/fourslash/getEmitOutputSingleFile.ts new file mode 100644 index 00000000000..13d0d6c9ac0 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputSingleFile.ts @@ -0,0 +1,19 @@ +/// + +// @Filename: inputFile1.ts +//// var x: any; +//// class Bar { +//// x : string; +//// y : number +//// } + +// @Filename: inputFile2.ts +//// var x: any; +//// class Foo{ +//// x : string; +//// y : number +//// } + +var outputFilename = "tests/cases/fourslash/singleFile.js"; +edit.enableSingleOutputFile(outputFilename); +verify.emitOutput(EmitOutputResult.Succeeded, outputFilename); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts new file mode 100644 index 00000000000..8f5a0f98d77 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts @@ -0,0 +1,7 @@ +/// + +// @Filename: semanticErrorsResult.ts +//// var x:number = "hello world"; + +// Only generate javscript file. The semantic error should not affect it +verify.emitOutput(EmitOutputResult.Succeeded,"tests/cases/fourslash/semanticErrorsResult.js"); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts new file mode 100644 index 00000000000..9bea96ecd0f --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts @@ -0,0 +1,8 @@ +/// + +// @Filename: semanticErrorsResult2.ts +//// var x:number = "hello world"; + +edit.enableDeclaration(); +// Fail to generate .d.ts file due to semantic error but succeeded in generate javascript file +verify.emitOutput(EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors,"tests/cases/fourslash/semanticErrorsResult2.js"); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts new file mode 100644 index 00000000000..9679b301300 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts @@ -0,0 +1,6 @@ +/// + +// @Filename: getEmitOutputWithSyntaxErrorsResult.ts +//// var x: + +verify.emitOutput(EmitOutputResult.FailedBecauseOfSyntaxErrors); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts new file mode 100644 index 00000000000..d0f72bc5adf --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts @@ -0,0 +1,10 @@ +/// + +// @Filename: syntaxErrorsResult2.ts +//// var x; +//// class M { +//// x : string; +//// y : numer + +edit.enableDeclaration(); +verify.emitOutput(EmitOutputResult.FailedBecauseOfSyntaxErrors); \ No newline at end of file From 2acd98e03e8059554a57d455b38025ddc0b5233a Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 4 Sep 2014 15:08:50 -0700 Subject: [PATCH 06/34] Minor spelling and spacing fix --- src/compiler/core.ts | 10 +++++----- src/compiler/parser.ts | 16 ++++++++-------- src/services/services.ts | 15 ++++++++------- src/services/shims.ts | 1 + tests/cases/fourslash/fourslash.ts | 8 ++++---- 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 7bc9c7e16b2..432ae6ab8cd 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -383,7 +383,7 @@ module ts { return [path.substr(0, rootLength)].concat(normalizedParts); } - export function getNormalizedPathComponents(path: string, getCurrentDirectory: ()=>string) { + export function getNormalizedPathComponents(path: string, getCurrentDirectory: () => string) { var path = normalizeSlashes(path); var rootLength = getRootLength(path); if (rootLength == 0) { @@ -396,7 +396,7 @@ module ts { return normalizedPathComponents(path, rootLength); } - export function getNormalizedPathFromPathCompoments(pathComponents: string[]) { + export function getNormalizedPathFromPathComponents(pathComponents: string[]) { if (pathComponents && pathComponents.length) { return pathComponents[0] + pathComponents.slice(1).join(directorySeparator); } @@ -444,7 +444,7 @@ module ts { } } - function getNormalizedPathOrUrlComponents(pathOrUrl: string, getCurrentDirectory: ()=>string) { + function getNormalizedPathOrUrlComponents(pathOrUrl: string, getCurrentDirectory: () => string) { if (isUrl(pathOrUrl)) { return getNormalizedPathComponentsOfUrl(pathOrUrl); } @@ -457,7 +457,7 @@ module ts { var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, getCurrentDirectory); var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, getCurrentDirectory); if (directoryComponents.length > 1 && directoryComponents[directoryComponents.length - 1] === "") { - // If the directory path given was of type test/cases/ then we really need components of directry to be only till its name + // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name // that is ["test", "cases", ""] needs to be actually ["test", "cases"] directoryComponents.length--; } @@ -483,7 +483,7 @@ module ts { } // Cant find the relative path, get the absolute path - var absolutePath = getNormalizedPathFromPathCompoments(pathComponents); + var absolutePath = getNormalizedPathFromPathComponents(pathComponents); if (isAbsolutePathAnUrl && isRootedDiskPath(absolutePath)) { absolutePath = "file:///" + absolutePath; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 64ac4683267..9e254936a6f 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3817,11 +3817,11 @@ module ts { // Each file contributes into common source file path if (!(sourceFile.flags & NodeFlags.DeclarationFile) && !fileExtensionIs(sourceFile.filename, ".js")) { - var sourcePathCompoments = getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory); - sourcePathCompoments.pop(); // FileName is not part of directory + var sourcePathComponents = getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory); + sourcePathComponents.pop(); // FileName is not part of directory if (commonPathComponents) { - for (var i = 0; i < Math.min(commonPathComponents.length, sourcePathCompoments.length); i++) { - if (commonPathComponents[i] !== sourcePathCompoments[i]) { + for (var i = 0; i < Math.min(commonPathComponents.length, sourcePathComponents.length); i++) { + if (commonPathComponents[i] !== sourcePathComponents[i]) { if (i === 0) { errors.push(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files)); return; @@ -3834,18 +3834,18 @@ module ts { } // If the fileComponent path completely matched and less than already found update the length - if (sourcePathCompoments.length < commonPathComponents.length) { - commonPathComponents.length = sourcePathCompoments.length; + if (sourcePathComponents.length < commonPathComponents.length) { + commonPathComponents.length = sourcePathComponents.length; } } else { // first file - commonPathComponents = sourcePathCompoments; + commonPathComponents = sourcePathComponents; } } }); - commonSourceDirectory = getNormalizedPathFromPathCompoments(commonPathComponents); + commonSourceDirectory = getNormalizedPathFromPathComponents(commonPathComponents); if (commonSourceDirectory) { // Make sure directory path ends with directory separator so this string can directly // used to replace with "" to get the relative path of the source file and the relative path doesn't diff --git a/src/services/services.ts b/src/services/services.ts index 5be6e29ff6f..afa3f200b6c 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1393,7 +1393,7 @@ module ts { var documentRegistry = documentRegistry; var cancellationToken = new CancellationTokenObject(host.getCancellationToken()); var activeCompletionSession: CompletionSession; // The current active completion session, used to get the completion entry details - var writter: (filename: string, data: string, writebyteordermark: boolean) => void = undefined; + var writer: (filename: string, data: string, writeByteOrderMark: boolean) => void = undefined; // Check if the localized messages json is set, otherwise query the host for it if (!TypeScript.LocalizedDiagnosticMessages) { @@ -1423,8 +1423,8 @@ module ts { return host.getDefaultLibFilename(); }, writeFile: (filename, data, writeByteOrderMark) => { - if (writter) { - writter(filename, data, writeByteOrderMark); + if (writer) { + writer(filename, data, writeByteOrderMark); return; } throw Error("Error occurs: Invalid invocation to writeFile"); @@ -2840,6 +2840,7 @@ module ts { } } } + function containErrors(diagnostics: Diagnostic[]): boolean { var hasError = forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); return hasError; @@ -2855,8 +2856,8 @@ module ts { emitOutputResult: undefined, }; - // Initialize writter for CompilerHost.writeFile - writter = function (fileName: string, data: string, writeByteOrderMark: boolean) { + // Initialize writer for CompilerHost.writeFile + writer = function (fileName: string, data: string, writeByteOrderMark: boolean) { var outputFile: OutputFile = { name: fileName, writeByteOrderMark: writeByteOrderMark, @@ -2893,8 +2894,8 @@ module ts { emitResult.emitOutputResult = EmitOutputResult.Succeeded; } - // Reset writter back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in an emitting stage - this.writter = undefined; + // Reset writer back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in an emitting stage + this.writer = undefined; return emitResult; } diff --git a/src/services/shims.ts b/src/services/shims.ts index 2e19db2815a..bf2c5f9b6f2 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -368,6 +368,7 @@ module ts { getDefaultLibFilename(): string { return this.shimHost.getDefaultLibFilename(); } + getCurrentDirectory(): string { return this.shimHost.getCurrentDirectory(); } diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 91bce54525a..d724b75e80e 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -46,10 +46,10 @@ enum TypingFidelity { // We have to duplicate EmitOutputResult from Services.ts to expose the enum to getEmitOutput testcases in fourslah enum EmitOutputResult { - Succeeded, - FailedBecauseOfSyntaxErrors, - FailedBecauseOfCompilerOptionsErrors, - FailedToGenerateDeclarationsBecauseOfSemanticErrors + Succeeded, + FailedBecauseOfSyntaxErrors, + FailedBecauseOfCompilerOptionsErrors, + FailedToGenerateDeclarationsBecauseOfSemanticErrors } module FourSlashInterface { From 451f92bc24b6a16e86bdd7c20a95dc8c55c1a782 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 4 Sep 2014 15:10:37 -0700 Subject: [PATCH 07/34] Expose function shouldEmitToOwnFile to be called in services.ts --- src/compiler/emitter.ts | 22 +++++++++++----------- src/services/services.ts | 8 +++++--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f8b64dafbce..fe96beab830 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -25,6 +25,14 @@ module ts { return indentStrings[1].length; } + export function shouldEmitToOwnFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { + if (!(sourceFile.flags & NodeFlags.DeclarationFile)) { + if ((isExternalModule(sourceFile) || !compilerOptions.out) && !fileExtensionIs(sourceFile.filename, ".js")) { + return true; + } + } + } + export function emitFiles(resolver: EmitResolver): EmitResult { var program = resolver.getProgram(); var compilerHost = program.getCompilerHost(); @@ -34,19 +42,11 @@ module ts { var newLine = program.getCompilerHost().getNewLine(); function getSourceFilePathInNewDir(newDirPath: string, sourceFile: SourceFile) { - var sourceFilePath = getNormalizedPathFromPathCompoments(getNormalizedPathComponents(sourceFile.filename, compilerHost.getCurrentDirectory)); + var sourceFilePath = getNormalizedPathFromPathComponents(getNormalizedPathComponents(sourceFile.filename, compilerHost.getCurrentDirectory)); sourceFilePath = sourceFilePath.replace(program.getCommonSourceDirectory(), ""); return combinePaths(newDirPath, sourceFilePath); } - function shouldEmitToOwnFile(sourceFile: SourceFile) { - if (!(sourceFile.flags & NodeFlags.DeclarationFile)) { - if ((isExternalModule(sourceFile) || !compilerOptions.out) && !fileExtensionIs(sourceFile.filename, ".js")) { - return true; - } - } - } - function getOwnEmitOutputFilePath(sourceFile: SourceFile, extension: string) { if (program.getCompilerOptions().outDir) { var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(getSourceFilePathInNewDir(program.getCompilerOptions().outDir, sourceFile)); @@ -3082,7 +3082,7 @@ module ts { function writeReferencePath(referencedFile: SourceFile) { var declFileName = referencedFile.flags & NodeFlags.DeclarationFile ? referencedFile.filename // Declaration file, use declaration file name - : shouldEmitToOwnFile(referencedFile) + : shouldEmitToOwnFile(referencedFile, compilerOptions) ? getOwnEmitOutputFilePath(referencedFile, ".d.ts") // Own output file so get the .d.ts file : getModuleNameFromFilename(compilerOptions.out) + ".d.ts";// Global out file @@ -3170,7 +3170,7 @@ module ts { } forEach(program.getSourceFiles(), sourceFile => { - if (shouldEmitToOwnFile(sourceFile)) { + if (shouldEmitToOwnFile(sourceFile, compilerOptions)) { var jsFilePath = getOwnEmitOutputFilePath(sourceFile, ".js"); emitFile(jsFilePath, sourceFile); } diff --git a/src/services/services.ts b/src/services/services.ts index afa3f200b6c..8569c859d58 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2849,8 +2849,10 @@ module ts { function getEmitOutput(filename: string): EmitOutput { synchronizeHostData(); filename = TypeScript.switchToForwardSlashes(filename); - var emitToSingleFile = program.getCompilerOptions().out; - var emitDeclaration = program.getCompilerOptions().declaration; + var sourceFile = getSourceFile(filename); + var compilerOptions = program.getCompilerOptions(); + var emitToSingleFile = ts.shouldEmitToOwnFile(program.getSourceFile(filename), compilerOptions); + var emitDeclaration = compilerOptions.declaration; var emitResult: EmitOutput = { outputFiles: [], emitOutputResult: undefined, @@ -2867,7 +2869,7 @@ module ts { } var syntacticDiagnostics = emitToSingleFile - ? program.getDiagnostics(getSourceFile(filename).getSourceFile()) + ? program.getDiagnostics(sourceFile) : program.getDiagnostics(); program.getGlobalDiagnostics(); From b0654dc0442282c0c7d3619984878c706653e4e3 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 4 Sep 2014 15:12:15 -0700 Subject: [PATCH 08/34] Remove enableSingleOutputFile boolean and use singleOutputFilename to check if singleOutputFile is specified --- src/harness/fourslash.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 01637a7e822..2a4124c842f 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -192,9 +192,6 @@ module FourSlash { // Whether or not to generate .d.ts file public enableDeclaration = false; - // Whether or not to generate one output javascript file - public enableSingleOutputFile = false; - // Output filename for single-output-file option public singleOutputFilename: string = undefined; @@ -463,10 +460,10 @@ module FourSlash { public verifyEmitOutput(state: ts.EmitOutputResult, filename?: string) { if (this.enableDeclaration) { - this.languageServiceShimHost.setCompilationSettings({generateDeclarationFiles: true}); + this.languageServiceShimHost.setCompilationSettings({ generateDeclarationFiles: true }); } - if (this.enableSingleOutputFile) { + if (this.singleOutputFilename !== undefined) { this.languageServiceShimHost.setCompilationSettings({ outFileOption: this.singleOutputFilename }); } From 623b97f2ec653f92bd72c5081b5c3e2721323a8e Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 4 Sep 2014 15:13:54 -0700 Subject: [PATCH 09/34] Add check if the compilationSetting object hasOwnProperty before add the property to TypeScriptLS object --- src/harness/harnessLanguageService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index e15063204ca..c30ea6d5ce7 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -248,7 +248,9 @@ module Harness.LanguageService { public setCompilationSettings(settings: any) { for (var key in settings) { - this.settings[key] = settings[key]; + if (settings.hasOwnProperty(key)) { + this.settings[key] = settings[key]; + } } } From 537f55ceded48f82d40c3e670381b26cf91c2eb0 Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 5 Sep 2014 16:15:12 -0700 Subject: [PATCH 10/34] Change getCurrentDirectory and getDefaultLibname from passing around function to its final value --- src/compiler/core.ts | 13 ++++++------- src/compiler/emitter.ts | 8 ++++---- src/compiler/parser.ts | 2 +- src/harness/projectsRunner.ts | 2 +- src/services/services.ts | 11 ++++------- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 432ae6ab8cd..4f50f311348 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -383,12 +383,11 @@ module ts { return [path.substr(0, rootLength)].concat(normalizedParts); } - export function getNormalizedPathComponents(path: string, getCurrentDirectory: () => string) { + export function getNormalizedPathComponents(path: string, currentDirectory: string) { var path = normalizeSlashes(path); var rootLength = getRootLength(path); if (rootLength == 0) { // If the path is not rooted it is relative to current directory - var currentDirectory = getCurrentDirectory(); path = combinePaths(normalizeSlashes(currentDirectory), path); rootLength = getRootLength(path); } @@ -444,18 +443,18 @@ module ts { } } - function getNormalizedPathOrUrlComponents(pathOrUrl: string, getCurrentDirectory: () => string) { + function getNormalizedPathOrUrlComponents(pathOrUrl: string, currentDirectory: string) { if (isUrl(pathOrUrl)) { return getNormalizedPathComponentsOfUrl(pathOrUrl); } else { - return getNormalizedPathComponents(pathOrUrl, getCurrentDirectory); + return getNormalizedPathComponents(pathOrUrl, currentDirectory); } } - export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, getCurrentDirectory: () => string, isAbsolutePathAnUrl: boolean) { - var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, getCurrentDirectory); - var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, getCurrentDirectory); + export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, isAbsolutePathAnUrl: boolean) { + var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory); + var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory); if (directoryComponents.length > 1 && directoryComponents[directoryComponents.length - 1] === "") { // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name // that is ["test", "cases", ""] needs to be actually ["test", "cases"] diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index fe96beab830..da67c2d2f13 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -42,7 +42,7 @@ module ts { var newLine = program.getCompilerHost().getNewLine(); function getSourceFilePathInNewDir(newDirPath: string, sourceFile: SourceFile) { - var sourceFilePath = getNormalizedPathFromPathComponents(getNormalizedPathComponents(sourceFile.filename, compilerHost.getCurrentDirectory)); + var sourceFilePath = getNormalizedPathFromPathComponents(getNormalizedPathComponents(sourceFile.filename, compilerHost.getCurrentDirectory())); sourceFilePath = sourceFilePath.replace(program.getCommonSourceDirectory(), ""); return combinePaths(newDirPath, sourceFilePath); } @@ -523,7 +523,7 @@ module ts { sourceMapData.sourceMapSources.push(getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, node.filename, - compilerHost.getCurrentDirectory, + compilerHost.getCurrentDirectory(), /*isAbsolutePathAnUrl*/ true)); sourceMapSourceIndex = sourceMapData.sourceMapSources.length - 1; @@ -640,7 +640,7 @@ module ts { sourceMapData.jsSourceMappingURL = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizePath(jsFilePath)), // get the relative sourceMapDir path based on jsFilePath combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap - compilerHost.getCurrentDirectory, + compilerHost.getCurrentDirectory(), /*isAbsolutePathAnUrl*/ true); } else { @@ -3089,7 +3089,7 @@ module ts { declFileName = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizeSlashes(jsFilePath)), declFileName, - compilerHost.getCurrentDirectory, + compilerHost.getCurrentDirectory(), /*isAbsolutePathAnUrl*/ false); referencePathsOutput += "/// " + newLine; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9e254936a6f..ffc30e8e690 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3817,7 +3817,7 @@ module ts { // Each file contributes into common source file path if (!(sourceFile.flags & NodeFlags.DeclarationFile) && !fileExtensionIs(sourceFile.filename, ".js")) { - var sourcePathComponents = getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory); + var sourcePathComponents = getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory()); sourcePathComponents.pop(); // FileName is not part of directory if (commonPathComponents) { for (var i = 0; i < Math.min(commonPathComponents.length, sourcePathComponents.length); i++) { diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 7a5fa51e147..b0f3e939d30 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -226,7 +226,7 @@ class ProjectRunner extends RunnerBase { ? filename : ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(filename); - var diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName, getCurrentDirectory, false); + var diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName, getCurrentDirectory(), false); if (ts.isRootedDiskPath(diskRelativeName) || diskRelativeName.substr(0, 3) === "../") { // If the generated output file recides in the parent folder or is rooted path, // we need to instead create files that can live in the project reference folder diff --git a/src/services/services.ts b/src/services/services.ts index 8569c859d58..1c6eebb9419 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1420,17 +1420,14 @@ module ts { getNewLine: () => "\r\n", // Need something that doesn't depend on sys.ts here getDefaultLibFilename: (): string => { - return host.getDefaultLibFilename(); + return ""; }, writeFile: (filename, data, writeByteOrderMark) => { - if (writer) { - writer(filename, data, writeByteOrderMark); - return; - } - throw Error("Error occurs: Invalid invocation to writeFile"); + writer(filename, data, writeByteOrderMark); }, getCurrentDirectory: (): string => { - return host.getCurrentDirectory(); + // Return empty string as in compilerHost using with Visual Studio should not need to getCurrentDirectory since CompilerHost should have absolute path already + return ""; } }; } From 6ef41a74c7f34a23dab93e70413c589ec47e2bbe Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 5 Sep 2014 16:18:39 -0700 Subject: [PATCH 11/34] Move checking semantic diagnostics into emitFiles function rather than getEmitOutput --- src/compiler/checker.ts | 6 ++++ src/compiler/emitter.ts | 24 ++++++++++++-- src/compiler/types.ts | 11 +++++++ src/harness/fourslash.ts | 6 ++-- src/services/services.ts | 50 +++++++++--------------------- tests/cases/fourslash/fourslash.ts | 17 +++++----- 6 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c96b2edc5b1..1d50ab4e196 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7181,6 +7181,11 @@ module ts { return target !== unknownSymbol && ((target.flags & SymbolFlags.Value) !== 0); } + function hasSemanticErrors() { + // Return true if there is any semantic error in a file or globally + return (getDiagnostics().length > 0) || (getGlobalDiagnostics().length > 0); + } + function shouldEmitDeclarations() { // If the declaration emit and there are no errors being reported in program or by checker // declarations can be emitted @@ -7258,6 +7263,7 @@ module ts { getNodeCheckFlags: getNodeCheckFlags, getEnumMemberValue: getEnumMemberValue, isTopLevelValueImportedViaEntityName: isTopLevelValueImportedViaEntityName, + hasSemanticErrors: hasSemanticErrors, shouldEmitDeclarations: shouldEmitDeclarations, isDeclarationVisible: isDeclarationVisible, isImplementationOfOverload: isImplementationOfOverload, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index da67c2d2f13..6a7efc5dbcc 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -48,8 +48,8 @@ module ts { } function getOwnEmitOutputFilePath(sourceFile: SourceFile, extension: string) { - if (program.getCompilerOptions().outDir) { - var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(getSourceFilePathInNewDir(program.getCompilerOptions().outDir, sourceFile)); + if (compilerOptions.outDir) { + var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(getSourceFilePathInNewDir(compilerOptions.outDir, sourceFile)); } else { var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(sourceFile.filename); @@ -3183,7 +3183,27 @@ module ts { diagnostics.sort(compareDiagnostics); diagnostics = deduplicateSortedDiagnostics(diagnostics); + var returnCode = EmitReturnStatus.Succeeded; + + // Check if there is any diagnostic in an error category; if so, there is an emitter error + var hasEmitterError = forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); + + if (resolver.hasSemanticErrors() && !compilerOptions.declaration) { + // There is an semantic errror when output javascript file + // Output JS file with semantic error + returnCode = EmitReturnStatus.JSGeneratedWithSemanticErrors; + } + else if (resolver.hasSemanticErrors() && compilerOptions.declaration) { + // There is an semantic errror when output javascript and declaration file + // Output JS file with semantic error, not output declaration file + returnCode = EmitReturnStatus.DeclarationGenerationSkipped; + } + else if (hasEmitterError) { + returnCode = EmitReturnStatus.EmitErrorsEncountered; + } + return { + emitResultStatus: returnCode, errors: diagnostics, sourceMaps: sourceMapDataList }; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c13b47a066c..e34afd7784e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -588,7 +588,17 @@ module ts { sourceMapDecodedMappings: SourceMapSpan[]; } + // Return code used by getEmitOutput function to indicate status of the function + export enum EmitReturnStatus { + Succeeded = 0, // All outputs generated as requested (.js, .map, .d.ts), no errors reported + AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, or compiler options errors, nothing generated + JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors + DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors + EmitErrorsEncountered = 4 // Emitter errors occured during emitting process + } + export interface EmitResult { + emitResultStatus: EmitReturnStatus; errors: Diagnostic[]; sourceMaps: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps } @@ -660,6 +670,7 @@ module ts { isTopLevelValueImportedViaEntityName(node: ImportDeclaration): boolean; getNodeCheckFlags(node: Node): NodeCheckFlags; getEnumMemberValue(node: EnumMember): number; + hasSemanticErrors(): boolean; shouldEmitDeclarations(): boolean; isDeclarationVisible(node: Declaration): boolean; isImplementationOfOverload(node: FunctionDeclaration): boolean; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 2a4124c842f..94b60420bb6 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -458,7 +458,7 @@ module FourSlash { } } - public verifyEmitOutput(state: ts.EmitOutputResult, filename?: string) { + public verifyEmitOutput(state: ts.EmitReturnStatus, filename?: string) { if (this.enableDeclaration) { this.languageServiceShimHost.setCompilationSettings({ generateDeclarationFiles: true }); } @@ -474,8 +474,8 @@ module FourSlash { var emit = this.languageService.getEmitOutput(this.activeFile.fileName); - if (emit.emitOutputResult !== state) { - throw new Error("Expected emitOutputResult '" + state + "', but actual emitOutputResult '" + emit.emitOutputResult + "'"); + if (emit.emitOutputStatus !== state) { + throw new Error("Expected emitOutputResult '" + state + "', but actual emitOutputResult '" + emit.emitOutputStatus + "'"); } var passed = true; diff --git a/src/services/services.ts b/src/services/services.ts index 1c6eebb9419..c49615f6782 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -663,16 +663,9 @@ module ts { docComment: string; } - export enum EmitOutputResult { - Succeeded, - FailedBecauseOfSyntaxErrors, - FailedBecauseOfCompilerOptionsErrors, - FailedToGenerateDeclarationsBecauseOfSemanticErrors - } - export interface EmitOutput { outputFiles: OutputFile[]; - emitOutputResult: EmitOutputResult; + emitOutputStatus: EmitReturnStatus; } export enum OutputFileType { @@ -2846,56 +2839,43 @@ module ts { function getEmitOutput(filename: string): EmitOutput { synchronizeHostData(); filename = TypeScript.switchToForwardSlashes(filename); - var sourceFile = getSourceFile(filename); + var sourceFile = program.getSourceFile(filename); var compilerOptions = program.getCompilerOptions(); - var emitToSingleFile = ts.shouldEmitToOwnFile(program.getSourceFile(filename), compilerOptions); + var emitToSingleFile = ts.shouldEmitToOwnFile(sourceFile, compilerOptions); var emitDeclaration = compilerOptions.declaration; - var emitResult: EmitOutput = { + var emitOutput: EmitOutput = { outputFiles: [], - emitOutputResult: undefined, + emitOutputStatus: undefined, }; // Initialize writer for CompilerHost.writeFile writer = function (fileName: string, data: string, writeByteOrderMark: boolean) { - var outputFile: OutputFile = { + emitOutput.outputFiles.push({ name: fileName, writeByteOrderMark: writeByteOrderMark, text: data - } - emitResult.outputFiles.push(outputFile); + }); } var syntacticDiagnostics = emitToSingleFile ? program.getDiagnostics(sourceFile) : program.getDiagnostics(); - program.getGlobalDiagnostics(); + var globalSyntacticDiagnostics = program.getGlobalDiagnostics(); // If there is any syntactic error, terminate the process if (containErrors(syntacticDiagnostics)) { - emitResult.emitOutputResult = EmitOutputResult.FailedBecauseOfSyntaxErrors; - return emitResult; + emitOutput.emitOutputStatus = EmitReturnStatus.AllOutputGenerationSkipped; + return emitOutput; } // Perform semantic and force a type check before emit to ensure that all symbols are updated - var semanticDiagnostics = emitToSingleFile - ? getFullTypeCheckChecker().getDiagnostics(getSourceFile(filename).getSourceFile()) - : getFullTypeCheckChecker().getDiagnostics(); - getFullTypeCheckChecker().getGlobalDiagnostics(); - var emitOutput = getFullTypeCheckChecker().emitFiles(); + // EmitFiles will report if there is an error from TypeChecker and Emitter + var emitFilesResult = getFullTypeCheckChecker().emitFiles(); + emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus; - if (emitDeclaration && containErrors(semanticDiagnostics)) { - emitResult.emitOutputResult = EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors; - } - else if (emitDeclaration && containErrors(emitOutput.errors)) { - emitResult.emitOutputResult = EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors; - } - else { - emitResult.emitOutputResult = EmitOutputResult.Succeeded; - } - - // Reset writer back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in an emitting stage + // Reset writer back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput this.writer = undefined; - return emitResult; + return emitOutput; } /// Syntactic features diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index d724b75e80e..9a6e03845e8 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -44,14 +44,17 @@ enum TypingFidelity { High = FourSlash.TypingFidelity.High } -// We have to duplicate EmitOutputResult from Services.ts to expose the enum to getEmitOutput testcases in fourslah -enum EmitOutputResult { - Succeeded, - FailedBecauseOfSyntaxErrors, - FailedBecauseOfCompilerOptionsErrors, - FailedToGenerateDeclarationsBecauseOfSemanticErrors +// Return code used by getEmitOutput function to indicate status of the function +// It is a duplicate of the one in types.ts to expose it to testcases in fourslash +enum EmitReturnStatus { + Succeeded = 0, // All outputs generated as requested (.js, .map, .d.ts), no errors reported + AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, or compiler options errors, nothing generated + JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors + DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors + EmitErrorsEncountered = 4 // Emitter errors occured during emitting process } + module FourSlashInterface { declare var FourSlash; @@ -263,7 +266,7 @@ module FourSlashInterface { FourSlash.currentTestState.verifyEval(expr, value); } - public emitOutput(expectedState: EmitOutputResult, expectedFilename?: string) { + public emitOutput(expectedState: EmitReturnStatus, expectedFilename?: string) { FourSlash.currentTestState.verifyEmitOutput(expectedState, expectedFilename); } From be4133a1622ad48d3272048721987d9d6e128521 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 8 Sep 2014 16:20:41 -0700 Subject: [PATCH 12/34] Add meta-data flag name to modify compilationSettings --- src/harness/fourslash.ts | 64 +++++++++++++++++++-------- src/harness/harnessLanguageService.ts | 5 +-- src/services/shims.ts | 5 ++- tests/cases/fourslash/fourslash.ts | 17 ------- 4 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 94b60420bb6..82a584d5f5e 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -122,9 +122,47 @@ module FourSlash { return s.replace(/[&<>"'\/]/g, ch => entityMap[ch]); } + // Name of ts.CompilerOptions properties that will be used by globalOptions + // To add additional option, add property into the compilerOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames + // Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data + var compilerOptMetadataNames = { + out: 'out', + outDir: 'outDir', + declaration: 'declaration', + sourceMap: 'sourceMap', + sourceRoot: 'sourceRoot' + }; + // List of allowed metadata names var fileMetadataNames = ['Filename']; - var globalMetadataNames = ['Module', 'Target', 'BaselineFile']; // Note: Only BaselineFile is actually supported at the moment + var globalMetadataNames = ['BaselineFile', compilerOptMetadataNames.out, compilerOptMetadataNames.outDir, compilerOptMetadataNames.declaration, compilerOptMetadataNames.outDir, + compilerOptMetadataNames.declaration, compilerOptMetadataNames.sourceMap, compilerOptMetadataNames.sourceRoot] + + function convertGlobalOptionsToCompilationSettings(globalOptions: { [idx: string]: string }): ts.CompilationSettings { + var settings: ts.CompilationSettings = {}; + // Convert all property in globalOptions into ts.CompilationSettings + for (var prop in globalOptions) { + if (globalOptions.hasOwnProperty(prop)) { + switch (prop) { + case compilerOptMetadataNames.out: + settings.outFileOption = globalOptions[prop]; + break; + case compilerOptMetadataNames.outDir: + settings.outDirOption = globalOptions[prop]; + break; + case compilerOptMetadataNames.declaration: + settings.generateDeclarationFiles = true; + break; + case compilerOptMetadataNames.sourceMap: + settings.mapSourceFiles = true; + break; + case compilerOptMetadataNames.sourceRoot: + settings.sourceRoot = globalOptions[prop] + } + } + } + return settings; + } export var currentTestState: TestState = null; @@ -189,12 +227,6 @@ module FourSlash { // Whether or not we should format on keystrokes public enableFormatting = true; - // Whether or not to generate .d.ts file - public enableDeclaration = false; - - // Output filename for single-output-file option - public singleOutputFilename: string = undefined; - public formatCodeOptions: ts.FormatCodeOptions; public cancellationToken: TestCancellationToken; @@ -205,11 +237,15 @@ module FourSlash { private scenarioActions: string[] = []; private taoInvalidReason: string = null; + constructor(public testData: FourSlashData) { // Initialize the language service with all the scripts this.cancellationToken = new TestCancellationToken(); this.languageServiceShimHost = new Harness.LanguageService.TypeScriptLS(this.cancellationToken); + var compilationSettings = convertGlobalOptionsToCompilationSettings(this.testData.globalOptions); + this.languageServiceShimHost.setCompilationSettings(compilationSettings); + var inputFiles: { unitName: string; content: string }[] = []; testData.files.forEach(file => { @@ -226,9 +262,9 @@ module FourSlash { //if (/require\(/.test(lastFile.content) || /reference\spath/.test(lastFile.content)) { // inputFiles.push({ unitName: lastFile.fileName, content: lastFile.content }); //} else { - inputFiles = testData.files.map(file => { - return { unitName: file.fileName, content: file.content }; - }); + inputFiles = testData.files.map(file => { + return { unitName: file.fileName, content: file.content }; + }); //} @@ -459,14 +495,6 @@ module FourSlash { } public verifyEmitOutput(state: ts.EmitReturnStatus, filename?: string) { - if (this.enableDeclaration) { - this.languageServiceShimHost.setCompilationSettings({ generateDeclarationFiles: true }); - } - - if (this.singleOutputFilename !== undefined) { - this.languageServiceShimHost.setCompilationSettings({ outFileOption: this.singleOutputFilename }); - } - var expectedFilenames:string[] = []; if (filename !== undefined) { expectedFilenames = filename.split(" "); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index c30ea6d5ce7..fdf246df9c5 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -134,8 +134,7 @@ module Harness.LanguageService { private ls: ts.LanguageServiceShim = null; private fileNameToScript: ts.Map = {}; - - private settings: any = {}; + private settings: ts.CompilationSettings = {}; constructor(private cancellationToken: ts.CancellationToken = CancellationToken.None) { } @@ -246,7 +245,7 @@ module Harness.LanguageService { return this.ls; } - public setCompilationSettings(settings: any) { + public setCompilationSettings(settings: ts.CompilationSettings) { for (var key in settings) { if (settings.hasOwnProperty(key)) { this.settings[key] = settings[key]; diff --git a/src/services/shims.ts b/src/services/shims.ts index bf2c5f9b6f2..605308d7b54 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -159,7 +159,7 @@ module ts { Asynchronous = 2, } - interface CompilationSettings { + export interface CompilationSettings { propagateEnumConstants?: boolean; removeComments?: boolean; watch?: boolean; @@ -179,6 +179,9 @@ module ts { gatherDiagnostics?: boolean; codepage?: number; emitBOM?: boolean; + + // Declare indexer signature + [index: string]: any; } function languageVersionToScriptTarget(languageVersion: LanguageVersion): ScriptTarget { diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 9a6e03845e8..577d2f4dc0a 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -446,23 +446,6 @@ module FourSlashInterface { public disableFormatting() { FourSlash.currentTestState.enableFormatting = false; } - - public enableDeclaration() { - FourSlash.currentTestState.enableDeclaration = true; - } - - public disableDeclaration() { - FourSlash.currentTestState.enableDeclaration = false; - } - - public enableSingleOutputFile(outputFilename: string) { - FourSlash.currentTestState.enableSingleOutputFile = true; - FourSlash.currentTestState.singleOutputFilename = outputFilename; - } - - public disableSingleOutputFile() { - FourSlash.currentTestState.enableSingleOutputFile = false; - } } export class debug { From 2a24ea585484d8c4c36c5ad01d7904cba440f0ac Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 8 Sep 2014 16:22:24 -0700 Subject: [PATCH 13/34] Fix spelling --- src/harness/fourslash.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 82a584d5f5e..c7b0443c2c1 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -516,7 +516,7 @@ module FourSlash { } if (!passed) { - var errorMessage = "Expected outputFilename '" + filename + "', but actualy outputFilename '"; + var errorMessage = "Expected outputFilename '" + filename + "', but actual outputFilename '"; emit.outputFiles.forEach((outputFile, idx, array) => { errorMessage += outputFile.name; if (idx !== emit.outputFiles.length - 1) { @@ -1274,7 +1274,7 @@ module FourSlash { private applyEdits(fileName: string, edits: ts.TextChange[], isFormattingEdit = false): number { // We get back a set of edits, but langSvc.editScript only accepts one at a time. Use this to keep track - // of the incremental offest from each edit to the next. Assumption is that these edit ranges don't overlap + // of the incremental offset from each edit to the next. Assumption is that these edit ranges don't overlap var runningOffset = 0; edits = edits.sort((a, b) => a.span.start() - b.span.start()); // Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters @@ -1351,7 +1351,7 @@ module FourSlash { var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!definitions || !definitions.length) { - throw new Error('goToDefinition failed - expected to at least one defintion location but got 0'); + throw new Error('goToDefinition failed - expected to at least one definition location but got 0'); } if (definitionIndex >= definitions.length) { @@ -1371,10 +1371,10 @@ module FourSlash { var foundDefinitions = definitions && definitions.length; if (foundDefinitions && negative) { - throw new Error('goToDefinition - expected to 0 defintion locations but got ' + definitions.length); + throw new Error('goToDefinition - expected to 0 definition locations but got ' + definitions.length); } else if (!foundDefinitions && !negative) { - throw new Error('goToDefinition - expected to at least one defintion location but got 0'); + throw new Error('goToDefinition - expected to at least one definition location but got 0'); } } @@ -2222,7 +2222,7 @@ module FourSlash { /// A list of ranges we've collected so far */ var localRanges: Range[] = []; - /// The latest position of the start of an unflushed plaintext area + /// The latest position of the start of an unflushed plain text area var lastNormalCharPosition: number = 0; /// The total number of metacharacters removed from the file (so far) From ed224ca9039759432286c1e7c22c5c7b4858f874 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 8 Sep 2014 16:23:38 -0700 Subject: [PATCH 14/34] Update getEmitOutput test files to use new meta-data flag --- .../cases/fourslash/getEmitOutputDeclarationMultiFiles.ts | 4 ++-- .../cases/fourslash/getEmitOutputDeclarationSingleFile.ts | 8 ++++---- tests/cases/fourslash/getEmitOutputNoErrors.ts | 2 +- tests/cases/fourslash/getEmitOutputSingleFile.ts | 4 ++-- tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts | 2 +- tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts | 4 ++-- tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts | 2 +- tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts b/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts index f2d7724e41b..5e2941f04fb 100644 --- a/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts +++ b/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts @@ -1,5 +1,6 @@ /// +// @declaration: true // @Filename: inputFile1.ts //// var x: number = 5; //// class Bar { @@ -16,6 +17,5 @@ var inputFile1 = "tests/cases/fourslash/inputFile1"; var inputFile2 = "tests/cases/fourslash/inputFile2"; -edit.enableDeclaration(); var outputFilenames = inputFile1 + ".js" + " " + inputFile2 + ".js" + " " + inputFile1 + ".d.ts" + " " + inputFile2 + ".d.ts"; -verify.emitOutput(EmitOutputResult.Succeeded, outputFilenames); \ No newline at end of file +verify.emitOutput(EmitReturnStatus.Succeeded); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts b/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts index 7366640650f..92acfda441f 100644 --- a/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts +++ b/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts @@ -1,6 +1,8 @@ /// +// @declaration: true // @Filename: inputFile1.ts +// @out: declSingleFile.js //// var x: number = 5; //// class Bar { //// x : string; @@ -14,10 +16,8 @@ //// y : number; //// } -var singleFilename = "tests/cases/fourslash/declSingleFile"; +var singleFilename = "declSingleFile"; var jsFilename = singleFilename + ".js"; var declFilename = singleFilename + ".d.ts"; -edit.enableSingleOutputFile(jsFilename); -edit.enableDeclaration(); var outputFilenames = jsFilename + " " + declFilename; -verify.emitOutput(EmitOutputResult.Succeeded, outputFilenames); \ No newline at end of file +verify.emitOutput(EmitReturnStatus.Succeeded, outputFilenames); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputNoErrors.ts b/tests/cases/fourslash/getEmitOutputNoErrors.ts index b3cdbc6c469..a2b2797ed66 100644 --- a/tests/cases/fourslash/getEmitOutputNoErrors.ts +++ b/tests/cases/fourslash/getEmitOutputNoErrors.ts @@ -7,4 +7,4 @@ //// y: string; //// } -verify.emitOutput(EmitOutputResult.Succeeded, "tests/cases/fourslash/noErrorsResult.js"); \ No newline at end of file +verify.emitOutput(EmitReturnStatus.Succeeded, "tests/cases/fourslash/noErrorsResult.js"); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSingleFile.ts b/tests/cases/fourslash/getEmitOutputSingleFile.ts index 13d0d6c9ac0..d273af02b86 100644 --- a/tests/cases/fourslash/getEmitOutputSingleFile.ts +++ b/tests/cases/fourslash/getEmitOutputSingleFile.ts @@ -1,5 +1,6 @@ /// +// @out: tests/cases/fourslash/singleFile.js // @Filename: inputFile1.ts //// var x: any; //// class Bar { @@ -15,5 +16,4 @@ //// } var outputFilename = "tests/cases/fourslash/singleFile.js"; -edit.enableSingleOutputFile(outputFilename); -verify.emitOutput(EmitOutputResult.Succeeded, outputFilename); \ No newline at end of file +verify.emitOutput(EmitReturnStatus.Succeeded, outputFilename); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts index 8f5a0f98d77..fb9929e36de 100644 --- a/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts @@ -4,4 +4,4 @@ //// var x:number = "hello world"; // Only generate javscript file. The semantic error should not affect it -verify.emitOutput(EmitOutputResult.Succeeded,"tests/cases/fourslash/semanticErrorsResult.js"); \ No newline at end of file +verify.emitOutput(EmitReturnStatus.JSGeneratedWithSemanticErrors,"tests/cases/fourslash/semanticErrorsResult.js"); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts index 9bea96ecd0f..bc7aacc0c91 100644 --- a/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts @@ -1,8 +1,8 @@ /// +// @declaration: true // @Filename: semanticErrorsResult2.ts //// var x:number = "hello world"; -edit.enableDeclaration(); // Fail to generate .d.ts file due to semantic error but succeeded in generate javascript file -verify.emitOutput(EmitOutputResult.FailedToGenerateDeclarationsBecauseOfSemanticErrors,"tests/cases/fourslash/semanticErrorsResult2.js"); \ No newline at end of file +verify.emitOutput(EmitReturnStatus.DeclarationGenerationSkipped,"tests/cases/fourslash/semanticErrorsResult2.js"); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts index 9679b301300..655de166c95 100644 --- a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts +++ b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts @@ -3,4 +3,4 @@ // @Filename: getEmitOutputWithSyntaxErrorsResult.ts //// var x: -verify.emitOutput(EmitOutputResult.FailedBecauseOfSyntaxErrors); \ No newline at end of file +verify.emitOutput(EmitReturnStatus.AllOutputGenerationSkipped); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts index d0f72bc5adf..b74b7c94830 100644 --- a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts +++ b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts @@ -1,10 +1,10 @@ /// +// @declaration // @Filename: syntaxErrorsResult2.ts //// var x; //// class M { //// x : string; //// y : numer -edit.enableDeclaration(); -verify.emitOutput(EmitOutputResult.FailedBecauseOfSyntaxErrors); \ No newline at end of file +verify.emitOutput(EmitReturnStatus.AllOutputGenerationSkipped); \ No newline at end of file From 6cba535f204d1c2ac9f6c8111843ab58397d020e Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 9 Sep 2014 17:41:34 -0700 Subject: [PATCH 15/34] Fix spelling --- src/compiler/types.ts | 4 ++-- src/harness/harness.ts | 4 ++-- src/services/services.ts | 36 ++++++++++++++++++------------------ src/services/shims.ts | 22 +++++++++++----------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e34afd7784e..70c02cf594f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -569,7 +569,7 @@ module ts { export interface SourceMapData { /** Where the sourcemap file is written */ sourceMapFilePath: string; - /** source map url written in the js file */ + /** source map URL written in the js file */ jsSourceMappingURL: string; /** Source map's file field - js file name*/ sourceMapFile: string; @@ -594,7 +594,7 @@ module ts { AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, or compiler options errors, nothing generated JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors - EmitErrorsEncountered = 4 // Emitter errors occured during emitting process + EmitErrorsEncountered = 4 // Emitter errors occurred during emitting process } export interface EmitResult { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 5ee3139d8f7..c227dac7bb0 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -826,7 +826,7 @@ module Harness { totalErrorsReported++; } - // Report glovbal errors: + // Report global errors: var globalErrors = diagnostics.filter(err => !err.filename); globalErrors.forEach(err => outputErrorText(err)); @@ -1016,7 +1016,7 @@ module Harness { } export module TestCaseParser { - /** all the necesarry information to set the right compiler settings */ + /** all the necessary information to set the right compiler settings */ export interface CompilerSetting { flag: string; value: string; diff --git a/src/services/services.ts b/src/services/services.ts index c49615f6782..722cab1d6a6 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -362,7 +362,7 @@ module ts { public update(scriptSnapshot: TypeScript.IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TypeScript.TextChangeRange): SourceFile { // See if we are currently holding onto a syntax tree. We may not be because we're // either a closed file, or we've just been lazy and haven't had to create the syntax - // tree yet. Access the field instead of the method so we don't accidently realize + // tree yet. Access the field instead of the method so we don't accidentally realize // the old syntax tree. var oldSyntaxTree = this.syntaxTree; @@ -1378,7 +1378,7 @@ module ts { var program: Program; // this checker is used to answer all LS questions except errors var typeInfoResolver: TypeChecker; - // the sole purpose of this checkes is to reutrn semantic diagnostics + // the sole purpose of this checker is to return semantic diagnostics // creation is deferred - use getFullTypeCheckChecker to get instance var fullTypeCheckChecker_doNotAccessDirectly: TypeChecker; var useCaseSensitivefilenames = false; @@ -1524,7 +1524,7 @@ module ts { sourceFile = documentRegistry.acquireDocument(filename, compilationSettings, scriptSnapshot, version, isOpen); } - // Remeber the new sourceFile + // Remember the new sourceFile sourceFilesByName[filename] = sourceFile; } @@ -1579,7 +1579,7 @@ module ts { var firstChar = displayName.charCodeAt(0); if (firstChar === TypeScript.CharacterCodes.singleQuote || firstChar === TypeScript.CharacterCodes.doubleQuote) { // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an - // invalid identifer name. We need to check if whatever was inside the quotes is actually a valid identifier name. + // invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name. displayName = TypeScript.stripStartAndEndQuotes(displayName); } @@ -1621,9 +1621,9 @@ module ts { } function isCompletionListBlocker(sourceUnit: TypeScript.SourceUnitSyntax, position: number): boolean { - // We shouldn't be getting a possition that is outside the file because + // We shouldn't be getting a position that is outside the file because // isEntirelyInsideComment can't handle when the position is out of bounds, - // callers should be fixed, however we should be resiliant to bad inputs + // callers should be fixed, however we should be resilient to bad inputs // so we return true (this position is a blocker for getting completions) if (position < 0 || position > TypeScript.fullWidth(sourceUnit)) { return true; @@ -1713,7 +1713,7 @@ module ts { var positionedToken = TypeScript.Syntax.findCompleteTokenOnLeft(sourceUnit, position, /*includeSkippedTokens*/true); if (positionedToken && position === TypeScript.end(positionedToken) && positionedToken.kind() == TypeScript.SyntaxKind.EndOfFileToken) { - // EndOfFile token is not intresting, get the one before it + // EndOfFile token is not interesting, get the one before it positionedToken = TypeScript. previousToken(positionedToken, /*includeSkippedTokens*/true); } @@ -1848,14 +1848,14 @@ module ts { // // get existing members // var existingMembers = compiler.getVisibleMemberSymbolsFromAST(node, document); - // // Add filtterd items to the completion list + // // Add filtered items to the completion list // getCompletionEntriesFromSymbols({ // symbols: filterContextualMembersList(contextualMembers.symbols, existingMembers, filename, position), // enclosingScopeSymbol: contextualMembers.enclosingScopeSymbol // }, entries); //} } - // Get scope memebers + // Get scope members else { isMemberCompletion = false; /// TODO filter meaning based on the current context @@ -2333,7 +2333,7 @@ module ts { // Could not find a symbol e.g. unknown identifier if (!symbol) { - // Even if we did not find a symbol, we have an identifer, so there is at least + // Even if we did not find a symbol, we have an identifier, so there is at least // one reference that we know of. return than instead of undefined. return [getReferenceEntry(node)]; } @@ -2599,7 +2599,7 @@ module ts { var propertySymbol = typeReferenceSymbol.members[propertyName]; if (propertySymbol) result.push(typeReferenceSymbol.members[propertyName]); - // Visit the typeReference as well to see if it directelly or indirectelly use that property + // Visit the typeReference as well to see if it directly or indirectly use that property getPropertySymbolsFromBaseTypes(typeReferenceSymbol, propertyName, result); } } @@ -2607,7 +2607,7 @@ module ts { } function isRelatableToSearchSet(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node): boolean { - // Unwrap symbols to get to the root (e.g. triansient symbols as a result of widenning) + // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) var referenceSymbolTarget = typeInfoResolver.getRootSymbol(referenceSymbol); // if it is in the list, then we are done @@ -2625,7 +2625,7 @@ module ts { } } - // Finally, try all properties with the same name in any type the containing type extened or implemented, and + // Finally, try all properties with the same name in any type the containing type extended or implemented, and // see if any is in the list if (referenceSymbol.parent && referenceSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { var result: Symbol[] = []; @@ -2781,7 +2781,7 @@ module ts { // intersects with the class in the value space. // To achieve that we will keep iterating until the result stabilizes. - // Remeber the last meaning + // Remember the last meaning var lastIterationMeaning = meaning; for (var i = 0, n = declarations.length; i < n; i++) { @@ -2796,7 +2796,7 @@ module ts { return meaning; } - /// A node is considedered a writeAccess iff it is a name of a declaration or a target of an assignment + /// A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment function isWriteAccess(node: Node): boolean { if (node.kind === SyntaxKind.Identifier && isDeclarationOrFunctionExpressionOrCatchVariableName(node)) { return true; @@ -2873,7 +2873,7 @@ module ts { var emitFilesResult = getFullTypeCheckChecker().emitFiles(); emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus; - // Reset writer back to underfined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput + // Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput this.writer = undefined; return emitOutput; } @@ -3154,7 +3154,7 @@ module ts { continue; } - // Looks to be within the trivia. See if we can find hte comment containing it. + // Looks to be within the trivia. See if we can find the comment containing it. var triviaList = matchPosition < TypeScript.start(token) ? token.leadingTrivia(syntaxTree.text) : token.trailingTrivia(syntaxTree.text); var trivia = findContainingComment(triviaList, matchPosition); if (trivia === null) { @@ -3362,7 +3362,7 @@ module ts { addResult(start - lastTokenOrCommentEnd, TokenClass.Whitespace); } - // Remeber the end of the last token + // Remember the end of the last token lastTokenOrCommentEnd = end; } diff --git a/src/services/shims.ts b/src/services/shims.ts index 605308d7b54..4f622d7a212 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -147,13 +147,13 @@ module ts { getDefaultCompilationSettings(): string; } - /// TODO: delete this, it is only needed untill the VS interface is updated + /// TODO: delete this, it is only needed until the VS interface is updated enum LanguageVersion { EcmaScript3 = 0, EcmaScript5 = 1, } - enum ModuleGenTarget { + export enum ModuleGenTarget { Unspecified = 0, Synchronous = 1, Asynchronous = 2, @@ -188,9 +188,9 @@ module ts { if (typeof languageVersion === "undefined") return undefined; switch (languageVersion) { - case LanguageVersion.EcmaScript3: return ScriptTarget.ES3; + case LanguageVersion.EcmaScript3: return ScriptTarget.ES3 case LanguageVersion.EcmaScript5: return ScriptTarget.ES5; - default: throw Error("unsuported LanguageVersion value: " + languageVersion); + default: throw Error("unsupported LanguageVersion value: " + languageVersion); } } @@ -201,7 +201,7 @@ module ts { case ModuleGenTarget.Asynchronous: return ModuleKind.AMD; case ModuleGenTarget.Synchronous: return ModuleKind.CommonJS; case ModuleGenTarget.Unspecified: return ModuleKind.None; - default: throw Error("unsuported ModuleGenTarget value: " + moduleGenTarget); + default: throw Error("unsupported ModuleGenTarget value: " + moduleGenTarget); } } @@ -211,7 +211,7 @@ module ts { switch (scriptTarget) { case ScriptTarget.ES3: return LanguageVersion.EcmaScript3; case ScriptTarget.ES5: return LanguageVersion.EcmaScript5; - default: throw Error("unsuported ScriptTarget value: " + scriptTarget); + default: throw Error("unsupported ScriptTarget value: " + scriptTarget); } } @@ -222,7 +222,7 @@ module ts { case ModuleKind.AMD: return ModuleGenTarget.Asynchronous; case ModuleKind.CommonJS: return ModuleGenTarget.Synchronous; case ModuleKind.None: return ModuleGenTarget.Unspecified; - default: throw Error("unsuported ModuleKind value: " + moduleKind); + default: throw Error("unsupported ModuleKind value: " + moduleKind); } } @@ -326,8 +326,8 @@ module ts { /// TODO: this should be pushed into VS. /// We can not ask the LS instance to resolve, as this will lead to asking the host about files it does not know about, - /// something it is not desinged to handle. for now make sure we never get a "noresolve == false". - /// This value should not matter, as the host runs resolution logic independentlly + /// something it is not designed to handle. for now make sure we never get a "noresolve == false". + /// This value should not matter, as the host runs resolution logic independently options.noResolve = true; return options; @@ -432,7 +432,7 @@ module ts { } // DISPOSE - // Ensure (almost) determinstic release of internal Javascript resources when + // Ensure (almost) deterministic release of internal Javascript resources when // some external native objects holds onto us (e.g. Com/Interop). public dispose(dummy: any): void { this.logger.log("dispose()"); @@ -859,7 +859,7 @@ module ts { } -/// TODO: this is used by VS, clean this up on both sides of the interfrace +/// TODO: this is used by VS, clean this up on both sides of the interface module TypeScript.Services { export var TypeScriptServicesFactory = ts.TypeScriptServicesFactory; } From 609d1bc92c55f85881637f4dfbdc8208a0c21b8d Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 9 Sep 2014 17:42:53 -0700 Subject: [PATCH 16/34] Chage test framework from manual comparing the result to using baseline; Add compilerOptions into fourslash --- src/harness/fourslash.ts | 110 ++++++++++------ tests/cases/fourslash/fourslash.d.ts | 179 +++++++++++++++++++++++++++ tests/cases/fourslash/fourslash.ts | 8 +- 3 files changed, 255 insertions(+), 42 deletions(-) create mode 100644 tests/cases/fourslash/fourslash.d.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c7b0443c2c1..8693ef6b2b5 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -130,13 +130,15 @@ module FourSlash { outDir: 'outDir', declaration: 'declaration', sourceMap: 'sourceMap', - sourceRoot: 'sourceRoot' + sourceRoot: 'sourceRoot', + mapRoot: 'mapRoot', + module: 'module', }; // List of allowed metadata names var fileMetadataNames = ['Filename']; var globalMetadataNames = ['BaselineFile', compilerOptMetadataNames.out, compilerOptMetadataNames.outDir, compilerOptMetadataNames.declaration, compilerOptMetadataNames.outDir, - compilerOptMetadataNames.declaration, compilerOptMetadataNames.sourceMap, compilerOptMetadataNames.sourceRoot] + compilerOptMetadataNames.declaration, compilerOptMetadataNames.sourceMap, compilerOptMetadataNames.sourceRoot, compilerOptMetadataNames.mapRoot, compilerOptMetadataNames.module] function convertGlobalOptionsToCompilationSettings(globalOptions: { [idx: string]: string }): ts.CompilationSettings { var settings: ts.CompilationSettings = {}; @@ -156,8 +158,26 @@ module FourSlash { case compilerOptMetadataNames.sourceMap: settings.mapSourceFiles = true; break; - case compilerOptMetadataNames.sourceRoot: - settings.sourceRoot = globalOptions[prop] + case compilerOptMetadataNames.sourceRoot: + settings.sourceRoot = globalOptions[prop]; + break; + case compilerOptMetadataNames.mapRoot: + settings.mapRoot = globalOptions[prop]; + break; + case compilerOptMetadataNames.module: + // create appropriate external module target for CompilationSettings + switch (globalOptions[prop]) { + case "AMD": + settings.moduleGenTarget = ts.ModuleGenTarget.Asynchronous; + break; + case "CommonJS": + settings.moduleGenTarget = ts.ModuleGenTarget.Synchronous; + break; + default: + settings.moduleGenTarget = ts.ModuleGenTarget.Unspecified; + break; + } + break; } } } @@ -494,40 +514,6 @@ module FourSlash { } } - public verifyEmitOutput(state: ts.EmitReturnStatus, filename?: string) { - var expectedFilenames:string[] = []; - if (filename !== undefined) { - expectedFilenames = filename.split(" "); - } - - var emit = this.languageService.getEmitOutput(this.activeFile.fileName); - - if (emit.emitOutputStatus !== state) { - throw new Error("Expected emitOutputResult '" + state + "', but actual emitOutputResult '" + emit.emitOutputStatus + "'"); - } - - var passed = true; - if (emit.outputFiles.length > 0) { - passed = expectedFilenames.every(expectedFilename => { - return emit.outputFiles.some(outputFile => { - return outputFile.name === expectedFilename; - }); - }); - } - - if (!passed) { - var errorMessage = "Expected outputFilename '" + filename + "', but actual outputFilename '"; - emit.outputFiles.forEach((outputFile, idx, array) => { - errorMessage += outputFile.name; - if (idx !== emit.outputFiles.length - 1) { - errorMessage += " "; - } - }); - errorMessage += "'"; - throw new Error(errorMessage); - } - } - public verifyMemberListContains(symbol: string, type?: string, docComment?: string, fullSymbolName?: string, kind?: string) { this.scenarioActions.push(''); this.scenarioActions.push(''); @@ -964,6 +950,54 @@ module FourSlash { true /* run immediately */); } + public baselineGetEmitOutput() { + this.taoInvalidReason = 'baselineCurrentFileBreakpointLocations impossible'; + + Harness.Baseline.runBaseline( + "Breakpoint Locations for " + this.activeFile.fileName, + this.testData.globalOptions['BaselineFile'], + () => { + var emitOutput = this.languageService.getEmitOutput(this.activeFile.fileName); + var emitOutputStatus = emitOutput.emitOutputStatus; + var resultString = ""; + + // Print emitOutputStatus in readable format + switch (emitOutputStatus) { + case ts.EmitReturnStatus.Succeeded: + resultString += "EmitOutputStatus : Succeeded\n"; + break; + case ts.EmitReturnStatus.AllOutputGenerationSkipped: + resultString += "EmitOutputStatus : AllOutputGenerationSkipped\n"; + break; + case ts.EmitReturnStatus.JSGeneratedWithSemanticErrors: + resultString += "EmitOutputStatus : JSGeneratedWithSemanticErrors\n"; + break; + case ts.EmitReturnStatus.DeclarationGenerationSkipped: + resultString += "EmitOutputStatus : DeclaratiionGenerationSkipped\n"; + break; + case ts.EmitReturnStatus.EmitErrorsEncountered: + resultString += "EmitOutputStatus : EmitErrorEncountered\n"; + break; + default: + resultString += "Invalid EmitOutputStatus\n"; + break; + } + + emitOutput.outputFiles.forEach((outputFile, idx, array) => { + var filename = "Filename : " + outputFile.name + "\n"; + if (filename.match("/*.js.map/") === undefined) { + var content = outputFile.text; + } + else { + var content = outputFile.text + "\n"; + } + resultString = resultString + filename + content + "\n"; + }); + return resultString; + }, + true /* run immediately */); + } + public printBreakpointLocation(pos: number) { Harness.IO.log(this.getBreakpointStatementLocation(pos)); } diff --git a/tests/cases/fourslash/fourslash.d.ts b/tests/cases/fourslash/fourslash.d.ts new file mode 100644 index 00000000000..b3ad5e000db --- /dev/null +++ b/tests/cases/fourslash/fourslash.d.ts @@ -0,0 +1,179 @@ +declare var FourSlash: any; +declare enum IncrementalEditValidation { + None, + SyntacticOnly, + Complete, +} +declare enum TypingFidelity { + /** Performs typing and formatting (if formatting is enabled) */ + Low, + /** Performs typing, checks completion lists, signature help, and formatting (if enabled) */ + High, +} +declare enum EmitReturnStatus { + Succeeded = 0, + AllOutputGenerationSkipped = 1, + JSGeneratedWithSemanticErrors = 2, + DeclarationGenerationSkipped = 3, + EmitErrorsEncountered = 4, +} +declare module FourSlashInterface { + interface Marker { + fileName: string; + position: number; + data?: any; + } + interface Range { + fileName: string; + start: number; + end: number; + marker?: Marker; + } + interface TextSpan { + start: number; + end: number; + } + class test_ { + markers(): Marker[]; + ranges(): Range[]; + } + class diagnostics { + validateTypeAtCurrentPosition(): any; + validateTypesAtPositions(...positions: number[]): any; + setEditValidation(validation: IncrementalEditValidation): void; + setTypingFidelity(fidelity: TypingFidelity): void; + } + class goTo { + marker(name?: string): void; + bof(): void; + eof(): void; + definition(definitionIndex?: number): void; + position(position: number, fileIndex?: number): any; + position(position: number, fileName?: string): any; + file(index: number): any; + file(name: string): any; + } + class verifyNegatable { + private negative; + not: verifyNegatable; + constructor(negative?: boolean); + memberListContains(symbol: string, type?: string, docComment?: string, fullSymbolName?: string, kind?: string): void; + memberListCount(expectedCount: number): void; + completionListContains(symbol: string, type?: string, docComment?: string, fullSymbolName?: string, kind?: string): void; + completionListItemsCountIsGreaterThan(count: number): void; + completionListIsEmpty(): void; + memberListIsEmpty(): void; + referencesCountIs(count: number): void; + referencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; + implementorsCountIs(count: number): void; + currentParameterIsVariable(): void; + signatureHelpPresent(): void; + errorExistsBetweenMarkers(startMarker: string, endMarker: string): void; + errorExistsAfterMarker(markerName?: string): void; + errorExistsBeforeMarker(markerName?: string): void; + quickInfoIs(typeName?: string, docComment?: string, symbolName?: string, kind?: string): void; + quickInfoSymbolNameIs(symbolName: any): void; + quickInfoExists(): void; + definitionLocationExists(): void; + } + class verify extends verifyNegatable { + caretAtMarker(markerName?: string): void; + indentationIs(numberOfSpaces: number): void; + indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number): void; + textAtCaretIs(text: string): void; + /** + Compiles the current file and evaluates 'expr' in a context containing + the emitted output, then compares (using ===) the result of that expression + to 'value'. Do not use this function with external modules as it is not supported. + */ + eval(expr: string, value: any): void; + emitOutput(expectedState: EmitReturnStatus, expectedFilename?: string): void; + currentLineContentIs(text: string): void; + currentFileContentIs(text: string): void; + currentParameterHelpArgumentNameIs(name: string): void; + currentParameterSpanIs(parameter: string): void; + currentParameterHelpArgumentDocCommentIs(docComment: string): void; + currentSignatureHelpDocCommentIs(docComment: string): void; + signatureHelpCountIs(expected: number): void; + currentSignatureParamterCountIs(expected: number): void; + currentSignatureTypeParamterCountIs(expected: number): void; + currentSignatureHelpIs(expected: string): void; + numberOfErrorsInCurrentFile(expected: number): void; + baselineCurrentFileBreakpointLocations(): void; + baselineCurrentFileNameOrDottedNameSpans(): void; + nameOrDottedNameSpanTextIs(text: string): void; + outliningSpansInCurrentFile(spans: TextSpan[]): void; + todoCommentsInCurrentFile(descriptors: string[]): void; + matchingBracePositionInCurrentFile(bracePosition: number, expectedMatchPosition: number): void; + noMatchingBracePositionInCurrentFile(bracePosition: number): void; + setVerifyDocComments(val: boolean): void; + getScriptLexicalStructureListCount(count: number): void; + getScriptLexicalStructureListContains(name: string, kind: string, fileName?: string, parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number): void; + navigationItemsListCount(count: number, searchValue: string, matchKind?: string): void; + navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parenetName?: string): void; + occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; + occurrencesAtPositionCount(expectedCount: number): void; + completionEntryDetailIs(entryName: string, type: string, docComment?: string, fullSymbolName?: string, kind?: string): void; + } + class edit { + backspace(count?: number): void; + deleteAtCaret(times?: number): void; + replace(start: number, length: number, text: string): void; + paste(text: string): void; + insert(text: string): void; + insertLine(text: string): void; + insertLines(...lines: string[]): void; + moveRight(count?: number): void; + moveLeft(count?: number): void; + enableFormatting(): void; + disableFormatting(): void; + } + class debug { + printCurrentParameterHelp(): void; + printCurrentFileState(): void; + printCurrentFileStateWithWhitespace(): void; + printCurrentFileStateWithoutCaret(): void; + printCurrentQuickInfo(): void; + printCurrentSignatureHelp(): void; + printMemberListMembers(): void; + printCompletionListMembers(): void; + printBreakpointLocation(pos: number): void; + printBreakpointAtCurrentLocation(): void; + printNameOrDottedNameSpans(pos: number): void; + printErrorList(): void; + printNavigationItems(searchValue?: string): void; + printScriptLexicalStructureItems(): void; + printReferences(): void; + printContext(): void; + } + class format { + document(): void; + selection(startMarker: string, endMarker: string): void; + setOption(name: string, value: number): any; + setOption(name: string, value: string): any; + setOption(name: string, value: boolean): any; + } + class cancellation { + resetCancelled(): void; + setCancelled(numberOfCalls?: number): void; + } +} +declare module fs { + var test: FourSlashInterface.test_; + var goTo: FourSlashInterface.goTo; + var verify: FourSlashInterface.verify; + var edit: FourSlashInterface.edit; + var debug: FourSlashInterface.debug; + var format: FourSlashInterface.format; + var diagnostics: FourSlashInterface.diagnostics; + var cancellation: FourSlashInterface.cancellation; +} +declare function verifyOperationIsCancelled(f: any): void; +declare var test: FourSlashInterface.test_; +declare var goTo: FourSlashInterface.goTo; +declare var verify: FourSlashInterface.verify; +declare var edit: FourSlashInterface.edit; +declare var debug: FourSlashInterface.debug; +declare var format: FourSlashInterface.format; +declare var diagnostics: FourSlashInterface.diagnostics; +declare var cancellation: FourSlashInterface.cancellation; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 577d2f4dc0a..1492492eae5 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -266,10 +266,6 @@ module FourSlashInterface { FourSlash.currentTestState.verifyEval(expr, value); } - public emitOutput(expectedState: EmitReturnStatus, expectedFilename?: string) { - FourSlash.currentTestState.verifyEmitOutput(expectedState, expectedFilename); - } - public currentLineContentIs(text: string) { FourSlash.currentTestState.verifyCurrentLineContent(text); } @@ -322,6 +318,10 @@ module FourSlashInterface { FourSlash.currentTestState.baselineCurrentFileNameOrDottedNameSpans(); } + public baselineGetEmitOutput() { + FourSlash.currentTestState.baselineGetEmitOutput(); + } + public nameOrDottedNameSpanTextIs(text: string) { FourSlash.currentTestState.verifyCurrentNameOrDottedNameSpanText(text); } From 4a1f652b66a7563e2c9e13646c34d73715c9a430 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 9 Sep 2014 17:43:10 -0700 Subject: [PATCH 17/34] Update testcases to use baseline --- .../getEmitOutputDeclarationMultiFiles.ts | 6 ++-- .../getEmitOutputDeclarationSingleFile.ts | 7 ++-- tests/cases/fourslash/getEmitOutputMapRoot.ts | 14 ++++++++ .../cases/fourslash/getEmitOutputNoErrors.ts | 5 +-- .../fourslash/getEmitOutputSingleFile.ts | 6 ++-- .../fourslash/getEmitOutputSingleFile2.ts | 32 +++++++++++++++++++ .../cases/fourslash/getEmitOutputSourceMap.ts | 13 ++++++++ .../fourslash/getEmitOutputSourceMap2.ts | 25 +++++++++++++++ .../fourslash/getEmitOutputSourceRoot.ts | 14 ++++++++ .../fourslash/getEmitOutputSourceRoot2.ts | 21 ++++++++++++ .../getEmitOutputWithEmitterErrors.ts | 13 ++++++++ .../getEmitOutputWithEmitterErrors2.ts | 12 +++++++ .../getEmitOutputWithSemanticErrors.ts | 6 ++-- .../getEmitOutputWithSemanticErrors2.ts | 6 ++-- .../getEmitOutputWithSyntaxErrors.ts | 5 +-- .../getEmitOutputWithSyntaxErrors2.ts | 10 ------ 16 files changed, 163 insertions(+), 32 deletions(-) create mode 100644 tests/cases/fourslash/getEmitOutputMapRoot.ts create mode 100644 tests/cases/fourslash/getEmitOutputSingleFile2.ts create mode 100644 tests/cases/fourslash/getEmitOutputSourceMap.ts create mode 100644 tests/cases/fourslash/getEmitOutputSourceMap2.ts create mode 100644 tests/cases/fourslash/getEmitOutputSourceRoot.ts create mode 100644 tests/cases/fourslash/getEmitOutputSourceRoot2.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithEmitterErrors.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithEmitterErrors2.ts delete mode 100644 tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts diff --git a/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts b/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts index 5e2941f04fb..942a48a4c73 100644 --- a/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts +++ b/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts @@ -1,5 +1,6 @@ /// +// @BaselineFile: getEmitOutputDeclarationMultiFiles.baseline // @declaration: true // @Filename: inputFile1.ts //// var x: number = 5; @@ -15,7 +16,4 @@ //// y : number; //// } -var inputFile1 = "tests/cases/fourslash/inputFile1"; -var inputFile2 = "tests/cases/fourslash/inputFile2"; -var outputFilenames = inputFile1 + ".js" + " " + inputFile2 + ".js" + " " + inputFile1 + ".d.ts" + " " + inputFile2 + ".d.ts"; -verify.emitOutput(EmitReturnStatus.Succeeded); \ No newline at end of file +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts b/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts index 92acfda441f..788519d0eab 100644 --- a/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts +++ b/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts @@ -1,5 +1,6 @@ /// +// @BaselineFile: getEmitOutputDeclarationSingleFile.baseline // @declaration: true // @Filename: inputFile1.ts // @out: declSingleFile.js @@ -16,8 +17,4 @@ //// y : number; //// } -var singleFilename = "declSingleFile"; -var jsFilename = singleFilename + ".js"; -var declFilename = singleFilename + ".d.ts"; -var outputFilenames = jsFilename + " " + declFilename; -verify.emitOutput(EmitReturnStatus.Succeeded, outputFilenames); \ No newline at end of file +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputMapRoot.ts b/tests/cases/fourslash/getEmitOutputMapRoot.ts new file mode 100644 index 00000000000..439c1e20372 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputMapRoot.ts @@ -0,0 +1,14 @@ +/// + +// @BaselineFile: getEmitOutputMapRoots.baseline +// @Filename: inputFile.ts +// @sourceMap: true +// @mapRoot: mapRootDir/ +//// var x = 109; +//// var foo = "hello world"; +//// class M { +//// x: number; +//// y: string; +//// } + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputNoErrors.ts b/tests/cases/fourslash/getEmitOutputNoErrors.ts index a2b2797ed66..955b1b77034 100644 --- a/tests/cases/fourslash/getEmitOutputNoErrors.ts +++ b/tests/cases/fourslash/getEmitOutputNoErrors.ts @@ -1,10 +1,11 @@ /// -// @Filename: noErrorsResult.ts +// @BaselineFile: getEmitOutputNoErrors.baseline +// @Filename: inputFile.ts //// var x; //// class M { //// x: number; //// y: string; //// } -verify.emitOutput(EmitReturnStatus.Succeeded, "tests/cases/fourslash/noErrorsResult.js"); \ No newline at end of file +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSingleFile.ts b/tests/cases/fourslash/getEmitOutputSingleFile.ts index d273af02b86..eccb8ce5cb5 100644 --- a/tests/cases/fourslash/getEmitOutputSingleFile.ts +++ b/tests/cases/fourslash/getEmitOutputSingleFile.ts @@ -1,6 +1,7 @@ /// -// @out: tests/cases/fourslash/singleFile.js +// @BaselineFile: getEmitOutputSingleFile.baseline +// @out: outputDir/singleFile.js // @Filename: inputFile1.ts //// var x: any; //// class Bar { @@ -15,5 +16,4 @@ //// y : number //// } -var outputFilename = "tests/cases/fourslash/singleFile.js"; -verify.emitOutput(EmitReturnStatus.Succeeded, outputFilename); \ No newline at end of file +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSingleFile2.ts b/tests/cases/fourslash/getEmitOutputSingleFile2.ts new file mode 100644 index 00000000000..c54ad22cc4f --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputSingleFile2.ts @@ -0,0 +1,32 @@ +/// + +// @BaselineFile: getEmitOutputSingleFile2.baseline +// @declaration: true +// @Filename: inputFile1.ts +// @out: declSingleFile.js +// @outDir: tests/cases/fourslash/ +//// var x: number = 5; +//// class Bar { +//// x : string; +//// y : number +//// } + +// @Filename: inputFile2.ts +//// var x1: string = "hello world"; +//// class Foo{ +//// x : string; +//// y : number; +//// } + +// @Filename: inputFile3.ts +////export var foo = 10; +////export var bar = "hello world" + +var singleFilename = "declSingleFile"; +var jsFilename = singleFilename + ".js"; +var declFilename = singleFilename + ".d.ts"; +var exportFilename = "tests/cases/fourslash/inputFile3" +var exportJSFilename = exportFilename + ".js"; +var exportDeclFilename = exportFilename + ".d.ts"; +var outputFilenames = jsFilename + " " + declFilename + " " + exportJSFilename + " " + exportDeclFilename; +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSourceMap.ts b/tests/cases/fourslash/getEmitOutputSourceMap.ts new file mode 100644 index 00000000000..753ac77a29a --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputSourceMap.ts @@ -0,0 +1,13 @@ +/// + +// @BaselineFile: getEmitOutputSourceMap.baseline +// @sourceMap: true +// @Filename: inputFile.ts +//// var x = 109; +//// var foo = "hello world"; +//// class M { +//// x: number; +//// y: string; +//// } + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSourceMap2.ts b/tests/cases/fourslash/getEmitOutputSourceMap2.ts new file mode 100644 index 00000000000..bc29c48eaca --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputSourceMap2.ts @@ -0,0 +1,25 @@ +/// + +// @BaselineFile: getEmitOutputSourceMap2.baseline +// @sourceMap: true +// @Filename: inputFile1.ts +// @outDir: sample/outDir +//// var x = 109; +//// var foo = "hello world"; +//// class M { +//// x: number; +//// y: string; +//// } + +// @Filename: inputFile2.ts +//// var intro = "hello world"; +//// if (intro !== undefined) { +//// var k = 10; +//// } + +var filename = "sample/outDir/sourceMapResult"; +var jsFilename = filename + ".js"; +var sourceMapFilename = filename + ".js.map"; +var outputFilenames = jsFilename + " " + sourceMapFilename; +verify.baselineGetEmitOutput(); +//verify.emitOutput(EmitReturnStatus.Succeeded, outputFilenames); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSourceRoot.ts b/tests/cases/fourslash/getEmitOutputSourceRoot.ts new file mode 100644 index 00000000000..c71015c17aa --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputSourceRoot.ts @@ -0,0 +1,14 @@ +/// + +// @BaselineFile: getEmitOutputSourceRoot.baseline +// @sourceMap: true +// @Filename: inputFile.ts +// @sourceRoot: sourceRootDir/ +//// var x = 109; +//// var foo = "hello world"; +//// class M { +//// x: number; +//// y: string; +//// } + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSourceRoot2.ts b/tests/cases/fourslash/getEmitOutputSourceRoot2.ts new file mode 100644 index 00000000000..1596269ed67 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputSourceRoot2.ts @@ -0,0 +1,21 @@ +/// + +// @BaselineFile: getEmitOutputSourceRootMultiFiles.baseline +// @Filename: inputFile1.ts +// @sourceMap: true +// @sourceRoot: sourceRootDir/ +//// var x = 109; +//// var foo = "hello world"; +//// class M { +//// x: number; +//// y: string; +//// } + +// @Filename: inputFile2.ts +//// var bar = "hello world Typescript"; +//// class C { +//// x: number; +//// y: string[]; +//// } + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithEmitterErrors.ts b/tests/cases/fourslash/getEmitOutputWithEmitterErrors.ts new file mode 100644 index 00000000000..78ab635a137 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithEmitterErrors.ts @@ -0,0 +1,13 @@ +/// + +// @BaselineFile: getEmitOutputWithEmitterErrors.baseline +// @declaration: true +// @Filename: inputFile.ts +////module M { +//// class C { } +//// export var foo = new C(); +////} + + +// Only generate javscript file. The semantic error should not affect it +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithEmitterErrors2.ts b/tests/cases/fourslash/getEmitOutputWithEmitterErrors2.ts new file mode 100644 index 00000000000..3a168143b83 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithEmitterErrors2.ts @@ -0,0 +1,12 @@ +/// + +// @BaselineFile: getEmitOutputWithEmitterErrors2.baseline +// @declaration: true +// @module: AMD +// @Filename: inputFile.ts +////class C { } +////export module M { +//// export var foo = new C(); +////} + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts index fb9929e36de..9388148954f 100644 --- a/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts @@ -1,7 +1,7 @@ /// -// @Filename: semanticErrorsResult.ts +// @BaselineFile: getEmitOutputWithSemanticErrors.baseline +// @Filename: inputFile.ts //// var x:number = "hello world"; -// Only generate javscript file. The semantic error should not affect it -verify.emitOutput(EmitReturnStatus.JSGeneratedWithSemanticErrors,"tests/cases/fourslash/semanticErrorsResult.js"); \ No newline at end of file +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts index bc7aacc0c91..5499f979b50 100644 --- a/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts @@ -1,8 +1,8 @@ /// +// @BaselineFile: getEmitOutputWithSemanticErrors2.baseline // @declaration: true -// @Filename: semanticErrorsResult2.ts +// @Filename: inputFile.ts //// var x:number = "hello world"; -// Fail to generate .d.ts file due to semantic error but succeeded in generate javascript file -verify.emitOutput(EmitReturnStatus.DeclarationGenerationSkipped,"tests/cases/fourslash/semanticErrorsResult2.js"); \ No newline at end of file +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts index 655de166c95..81631b3d4d0 100644 --- a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts +++ b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts @@ -1,6 +1,7 @@ /// -// @Filename: getEmitOutputWithSyntaxErrorsResult.ts +// @BaselineFile: getEmitOutputWithSyntaxErrors.baseline +// @Filename: inputFile.ts //// var x: -verify.emitOutput(EmitReturnStatus.AllOutputGenerationSkipped); \ No newline at end of file +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts deleted file mode 100644 index b74b7c94830..00000000000 --- a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors2.ts +++ /dev/null @@ -1,10 +0,0 @@ -/// - -// @declaration -// @Filename: syntaxErrorsResult2.ts -//// var x; -//// class M { -//// x : string; -//// y : numer - -verify.emitOutput(EmitReturnStatus.AllOutputGenerationSkipped); \ No newline at end of file From 9bbbdec0c222cad9fa132c3339bfbdd3f363eef1 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 9 Sep 2014 18:01:21 -0700 Subject: [PATCH 18/34] Check for repeating meta-data flag. --- src/harness/fourslash.ts | 4 ++++ tests/cases/fourslash/getEmitOutputSourceMap2.ts | 7 +------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 8693ef6b2b5..de789680284 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2147,6 +2147,10 @@ module FourSlash { currentFileOptions[match[1]] = match[2]; } } else { + // Check if the match is already existed in the global options + if (opts[match[1]] !== undefined) { + throw new Error("Global Option : '" + match[1] + "' is already existed"); + } opts[match[1]] = match[2]; } } diff --git a/tests/cases/fourslash/getEmitOutputSourceMap2.ts b/tests/cases/fourslash/getEmitOutputSourceMap2.ts index bc29c48eaca..b3977095b82 100644 --- a/tests/cases/fourslash/getEmitOutputSourceMap2.ts +++ b/tests/cases/fourslash/getEmitOutputSourceMap2.ts @@ -17,9 +17,4 @@ //// var k = 10; //// } -var filename = "sample/outDir/sourceMapResult"; -var jsFilename = filename + ".js"; -var sourceMapFilename = filename + ".js.map"; -var outputFilenames = jsFilename + " " + sourceMapFilename; -verify.baselineGetEmitOutput(); -//verify.emitOutput(EmitReturnStatus.Succeeded, outputFilenames); \ No newline at end of file +verify.baselineGetEmitOutput(); \ No newline at end of file From 0435c1408187e65b67d3a5d09147d5915f466466 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 3 Sep 2014 11:07:03 -0700 Subject: [PATCH 19/34] Add getEmitOutput and update call to getCurrentDirectory --- src/compiler/core.ts | 13 +++++++------ src/compiler/emitter.ts | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 4f50f311348..5207f4c7d81 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -383,11 +383,12 @@ module ts { return [path.substr(0, rootLength)].concat(normalizedParts); } - export function getNormalizedPathComponents(path: string, currentDirectory: string) { + export function getNormalizedPathComponents(path: string, getCurrentDirectory: ()=>string) { var path = normalizeSlashes(path); var rootLength = getRootLength(path); if (rootLength == 0) { // If the path is not rooted it is relative to current directory + var currentDirectory = getCurrentDirectory(); path = combinePaths(normalizeSlashes(currentDirectory), path); rootLength = getRootLength(path); } @@ -443,18 +444,18 @@ module ts { } } - function getNormalizedPathOrUrlComponents(pathOrUrl: string, currentDirectory: string) { + function getNormalizedPathOrUrlComponents(pathOrUrl: string, getCurrentDirectory: ()=>string) { if (isUrl(pathOrUrl)) { return getNormalizedPathComponentsOfUrl(pathOrUrl); } else { - return getNormalizedPathComponents(pathOrUrl, currentDirectory); + return getNormalizedPathComponents(pathOrUrl, getCurrentDirectory); } } - export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, isAbsolutePathAnUrl: boolean) { - var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory); - var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory); + export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, getCurrentDirectory: () => string, isAbsolutePathAnUrl: boolean) { + var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, getCurrentDirectory); + var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, getCurrentDirectory); if (directoryComponents.length > 1 && directoryComponents[directoryComponents.length - 1] === "") { // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name // that is ["test", "cases", ""] needs to be actually ["test", "cases"] diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6a7efc5dbcc..f0883f9b6b0 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -523,7 +523,7 @@ module ts { sourceMapData.sourceMapSources.push(getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, node.filename, - compilerHost.getCurrentDirectory(), + compilerHost.getCurrentDirectory, /*isAbsolutePathAnUrl*/ true)); sourceMapSourceIndex = sourceMapData.sourceMapSources.length - 1; @@ -640,7 +640,7 @@ module ts { sourceMapData.jsSourceMappingURL = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizePath(jsFilePath)), // get the relative sourceMapDir path based on jsFilePath combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap - compilerHost.getCurrentDirectory(), + compilerHost.getCurrentDirectory, /*isAbsolutePathAnUrl*/ true); } else { @@ -3089,7 +3089,7 @@ module ts { declFileName = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizeSlashes(jsFilePath)), declFileName, - compilerHost.getCurrentDirectory(), + compilerHost.getCurrentDirectory, /*isAbsolutePathAnUrl*/ false); referencePathsOutput += "/// " + newLine; From 271bb29c94b584601e5b994d19d82045481f62b8 Mon Sep 17 00:00:00 2001 From: Yui T Date: Thu, 4 Sep 2014 15:08:50 -0700 Subject: [PATCH 20/34] Minor spelling and spacing fix --- src/compiler/core.ts | 4 ++-- tests/cases/fourslash/fourslash.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 5207f4c7d81..432ae6ab8cd 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -383,7 +383,7 @@ module ts { return [path.substr(0, rootLength)].concat(normalizedParts); } - export function getNormalizedPathComponents(path: string, getCurrentDirectory: ()=>string) { + export function getNormalizedPathComponents(path: string, getCurrentDirectory: () => string) { var path = normalizeSlashes(path); var rootLength = getRootLength(path); if (rootLength == 0) { @@ -444,7 +444,7 @@ module ts { } } - function getNormalizedPathOrUrlComponents(pathOrUrl: string, getCurrentDirectory: ()=>string) { + function getNormalizedPathOrUrlComponents(pathOrUrl: string, getCurrentDirectory: () => string) { if (isUrl(pathOrUrl)) { return getNormalizedPathComponentsOfUrl(pathOrUrl); } diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 1492492eae5..836e139c61c 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -54,7 +54,6 @@ enum EmitReturnStatus { EmitErrorsEncountered = 4 // Emitter errors occured during emitting process } - module FourSlashInterface { declare var FourSlash; From cf2214bba0a10e9768d6417cb9791baaac2f1a62 Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 5 Sep 2014 16:15:12 -0700 Subject: [PATCH 21/34] Change getCurrentDirectory and getDefaultLibname from passing around function to its final value --- src/compiler/core.ts | 13 ++++++------- src/compiler/emitter.ts | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 432ae6ab8cd..4f50f311348 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -383,12 +383,11 @@ module ts { return [path.substr(0, rootLength)].concat(normalizedParts); } - export function getNormalizedPathComponents(path: string, getCurrentDirectory: () => string) { + export function getNormalizedPathComponents(path: string, currentDirectory: string) { var path = normalizeSlashes(path); var rootLength = getRootLength(path); if (rootLength == 0) { // If the path is not rooted it is relative to current directory - var currentDirectory = getCurrentDirectory(); path = combinePaths(normalizeSlashes(currentDirectory), path); rootLength = getRootLength(path); } @@ -444,18 +443,18 @@ module ts { } } - function getNormalizedPathOrUrlComponents(pathOrUrl: string, getCurrentDirectory: () => string) { + function getNormalizedPathOrUrlComponents(pathOrUrl: string, currentDirectory: string) { if (isUrl(pathOrUrl)) { return getNormalizedPathComponentsOfUrl(pathOrUrl); } else { - return getNormalizedPathComponents(pathOrUrl, getCurrentDirectory); + return getNormalizedPathComponents(pathOrUrl, currentDirectory); } } - export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, getCurrentDirectory: () => string, isAbsolutePathAnUrl: boolean) { - var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, getCurrentDirectory); - var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, getCurrentDirectory); + export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, isAbsolutePathAnUrl: boolean) { + var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory); + var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory); if (directoryComponents.length > 1 && directoryComponents[directoryComponents.length - 1] === "") { // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name // that is ["test", "cases", ""] needs to be actually ["test", "cases"] diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f0883f9b6b0..6a7efc5dbcc 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -523,7 +523,7 @@ module ts { sourceMapData.sourceMapSources.push(getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, node.filename, - compilerHost.getCurrentDirectory, + compilerHost.getCurrentDirectory(), /*isAbsolutePathAnUrl*/ true)); sourceMapSourceIndex = sourceMapData.sourceMapSources.length - 1; @@ -640,7 +640,7 @@ module ts { sourceMapData.jsSourceMappingURL = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizePath(jsFilePath)), // get the relative sourceMapDir path based on jsFilePath combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap - compilerHost.getCurrentDirectory, + compilerHost.getCurrentDirectory(), /*isAbsolutePathAnUrl*/ true); } else { @@ -3089,7 +3089,7 @@ module ts { declFileName = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizeSlashes(jsFilePath)), declFileName, - compilerHost.getCurrentDirectory, + compilerHost.getCurrentDirectory(), /*isAbsolutePathAnUrl*/ false); referencePathsOutput += "/// " + newLine; From 7ab51c6e2bc26942cbc3a9809aa414c0858990b0 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 9 Sep 2014 18:19:50 -0700 Subject: [PATCH 22/34] Merge from master --- src/compiler/emitter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6a7efc5dbcc..3a38a78c076 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3104,7 +3104,7 @@ module ts { // All the references that are not going to be part of same file if ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference - shouldEmitToOwnFile(referencedFile) || // This is referenced file is emitting its own js file + shouldEmitToOwnFile(referencedFile, compilerOptions) || // This is referenced file is emitting its own js file !addedGlobalFileReference) { // Or the global out file corresponding to this reference was not added writeReferencePath(referencedFile); From 7b0662be9edaa8941b390d64b2a0b6186cc7693a Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 10 Sep 2014 10:19:49 -0700 Subject: [PATCH 23/34] Remove getDirectory from LanguageServiceShimHost --- src/harness/harnessLanguageService.ts | 8 -------- src/services/services.ts | 2 -- 2 files changed, 10 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index fdf246df9c5..03c3436f9d5 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -180,14 +180,6 @@ module Harness.LanguageService { throw new Error("No script with name '" + fileName + "'"); } - public getDefaultLibFilename(): string { - return undefined; - } - - public getCurrentDirectory(): string { - return undefined; - } - ////////////////////////////////////////////////////////////////////// // ILogger implementation // diff --git a/src/services/services.ts b/src/services/services.ts index 722cab1d6a6..a110a4b9635 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -417,8 +417,6 @@ module ts { getScriptSnapshot(fileName: string): TypeScript.IScriptSnapshot; getLocalizedDiagnosticMessages(): any; getCancellationToken(): CancellationToken; - getDefaultLibFilename(): string; - getCurrentDirectory(): string; } // From bf7e7b6cc2c624c91fa4ca35553cfb0ccadcf8bf Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 10 Sep 2014 15:57:01 -0700 Subject: [PATCH 24/34] Fix spelling --- tests/cases/fourslash/fourslash.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 836e139c61c..184059aa0e0 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -51,7 +51,7 @@ enum EmitReturnStatus { AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, or compiler options errors, nothing generated JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors - EmitErrorsEncountered = 4 // Emitter errors occured during emitting process + EmitErrorsEncountered = 4 // Emitter errors occurred during emitting process } module FourSlashInterface { From 26fbb987bbdb65ce7c9b7dbc64a6050bde0cf031 Mon Sep 17 00:00:00 2001 From: Yui T Date: Wed, 10 Sep 2014 16:10:40 -0700 Subject: [PATCH 25/34] Remove getCurrentDirectory and getDefaultLibFilename from LanguageServiceShimHost --- src/services/shims.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/services/shims.ts b/src/services/shims.ts index 4f622d7a212..ba7c73d87e3 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -53,8 +53,6 @@ module ts { getScriptSnapshot(fileName: string): ScriptSnapshotShim; getLocalizedDiagnosticMessages(): string; getCancellationToken(): CancellationToken; - getDefaultLibFilename(): string; - getCurrentDirectory(): string; } // @@ -367,14 +365,6 @@ module ts { public getCancellationToken(): CancellationToken { return this.shimHost.getCancellationToken(); } - - getDefaultLibFilename(): string { - return this.shimHost.getDefaultLibFilename(); - } - - getCurrentDirectory(): string { - return this.shimHost.getCurrentDirectory(); - } } function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any): any { From 0b06ddcc9a3ce02fdd84a00cf9ab4a456028071f Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 12 Sep 2014 12:57:00 -0700 Subject: [PATCH 26/34] Fix getEmitOutput to only output one file except when 'out' flag is specified. Add testcases --- src/compiler/checker.ts | 15 +- src/compiler/emitter.ts | 66 ++++--- src/compiler/types.ts | 3 +- src/harness/fourslash.ts | 174 +++++++++-------- src/services/services.ts | 32 +++- tests/cases/fourslash/fourslash.d.ts | 179 ------------------ .../getEmitOutputDeclarationMultiFiles.ts | 3 + .../getEmitOutputDeclarationSingleFile.ts | 4 +- tests/cases/fourslash/getEmitOutputMapRoot.ts | 5 +- .../cases/fourslash/getEmitOutputNoErrors.ts | 1 + .../fourslash/getEmitOutputOnlyOneFile.ts | 20 ++ .../fourslash/getEmitOutputSingleFile.ts | 2 + .../fourslash/getEmitOutputSingleFile2.ts | 11 +- .../cases/fourslash/getEmitOutputSourceMap.ts | 2 + .../fourslash/getEmitOutputSourceMap2.ts | 5 +- .../fourslash/getEmitOutputSourceRoot.ts | 4 +- ...s => getEmitOutputSourceRootMultiFiles.ts} | 5 +- .../getEmitOutputWithEmitterErrors.ts | 2 + .../getEmitOutputWithEmitterErrors2.ts | 2 + .../getEmitOutputWithSemanticErrors.ts | 2 + .../getEmitOutputWithSemanticErrors2.ts | 2 + .../getEmitOutputWithSyntaxErrors.ts | 2 + 22 files changed, 223 insertions(+), 318 deletions(-) delete mode 100644 tests/cases/fourslash/fourslash.d.ts create mode 100644 tests/cases/fourslash/getEmitOutputOnlyOneFile.ts rename tests/cases/fourslash/{getEmitOutputSourceRoot2.ts => getEmitOutputSourceRootMultiFiles.ts} (84%) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1d50ab4e196..b2f4f656fe7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7183,15 +7183,7 @@ module ts { function hasSemanticErrors() { // Return true if there is any semantic error in a file or globally - return (getDiagnostics().length > 0) || (getGlobalDiagnostics().length > 0); - } - - function shouldEmitDeclarations() { - // If the declaration emit and there are no errors being reported in program or by checker - // declarations can be emitted - return compilerOptions.declaration && - !program.getDiagnostics().length && - !getDiagnostics().length; + return getDiagnostics().length > 0 || getGlobalDiagnostics().length > 0; } function isReferencedImportDeclaration(node: ImportDeclaration): boolean { @@ -7252,7 +7244,7 @@ module ts { writeTypeToTextWriter(getReturnTypeOfSignature(signature), enclosingDeclaration, flags , writer); } - function invokeEmitter() { + function invokeEmitter(targetSourceFile?: SourceFile) { var resolver: EmitResolver = { getProgram: () => program, getLocalNameOfContainer: getLocalNameOfContainer, @@ -7264,7 +7256,6 @@ module ts { getEnumMemberValue: getEnumMemberValue, isTopLevelValueImportedViaEntityName: isTopLevelValueImportedViaEntityName, hasSemanticErrors: hasSemanticErrors, - shouldEmitDeclarations: shouldEmitDeclarations, isDeclarationVisible: isDeclarationVisible, isImplementationOfOverload: isImplementationOfOverload, writeTypeAtLocation: writeTypeAtLocation, @@ -7274,7 +7265,7 @@ module ts { isImportDeclarationEntityNameReferenceDeclarationVisibile: isImportDeclarationEntityNameReferenceDeclarationVisibile }; checkProgram(); - return emitFiles(resolver); + return emitFiles(resolver, targetSourceFile); } function initializeTypeChecker() { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 3a38a78c076..f3375a4d9e0 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -25,15 +25,21 @@ module ts { return indentStrings[1].length; } - export function shouldEmitToOwnFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { + export function shouldEmitToOwnFile(sourceFile: SourceFile, compilerOptions: CompilerOptions): boolean { if (!(sourceFile.flags & NodeFlags.DeclarationFile)) { if ((isExternalModule(sourceFile) || !compilerOptions.out) && !fileExtensionIs(sourceFile.filename, ".js")) { return true; } + return false; } + return false; + } + export function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) { + return isExternalModule(sourceFile) || (sourceFile.flags & NodeFlags.DeclarationFile) !== 0; } - export function emitFiles(resolver: EmitResolver): EmitResult { + // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compilerOnSave feature + export function emitFiles(resolver: EmitResolver, targetSourceFile?: SourceFile): EmitResult { var program = resolver.getProgram(); var compilerHost = program.getCompilerHost(); var compilerOptions = program.getCompilerOptions(); @@ -58,10 +64,6 @@ module ts { return emitOutputFilePathWithoutExtension + extension; } - function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) { - return isExternalModule(sourceFile) || (sourceFile.flags & NodeFlags.DeclarationFile) !== 0; - } - function getFirstConstructorWithBody(node: ClassDeclaration): ConstructorDeclaration { return forEach(node.members, member => { if (member.kind === SyntaxKind.Constructor && (member).body) { @@ -3161,44 +3163,50 @@ module ts { } } - var shouldEmitDeclarations = resolver.shouldEmitDeclarations(); + var hasSemanticErros = resolver.hasSemanticErrors(); + var returnCode = EmitReturnStatus.Succeeded; + function emitFile(jsFilePath: string, sourceFile?: SourceFile) { emitJavaScript(jsFilePath, sourceFile); - if (shouldEmitDeclarations) { + // Update the returnCode with appropriate value depended on whether we have semantic errors + if (!hasSemanticErros && compilerOptions.declaration) { + returnCode = EmitReturnStatus.Succeeded; emitDeclarations(jsFilePath, sourceFile); } + else if (hasSemanticErros && compilerOptions.declaration) { + returnCode = EmitReturnStatus.DeclarationGenerationSkipped; + } + else if (hasSemanticErros && !compilerOptions.declaration) { + returnCode = EmitReturnStatus.JSGeneratedWithSemanticErrors; + } + } + + if (targetSourceFile === undefined) { + forEach(program.getSourceFiles(), sourceFile => { + if (shouldEmitToOwnFile(sourceFile, compilerOptions)) { + var jsFilePath = getOwnEmitOutputFilePath(sourceFile, ".js"); + emitFile(jsFilePath, sourceFile); + } + }); + } + else { + // Emit only one file specified in targetFilename. This is mainly used in compilerOnSave feature + var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, ".js"); + emitFile(jsFilePath, targetSourceFile); } - forEach(program.getSourceFiles(), sourceFile => { - if (shouldEmitToOwnFile(sourceFile, compilerOptions)) { - var jsFilePath = getOwnEmitOutputFilePath(sourceFile, ".js"); - emitFile(jsFilePath, sourceFile); - } - }); if (compilerOptions.out) { emitFile(compilerOptions.out); } - + // Sort and make the unique list of diagnostics diagnostics.sort(compareDiagnostics); diagnostics = deduplicateSortedDiagnostics(diagnostics); - var returnCode = EmitReturnStatus.Succeeded; - - // Check if there is any diagnostic in an error category; if so, there is an emitter error + // Update returnCode if there is any EmitterError var hasEmitterError = forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); - if (resolver.hasSemanticErrors() && !compilerOptions.declaration) { - // There is an semantic errror when output javascript file - // Output JS file with semantic error - returnCode = EmitReturnStatus.JSGeneratedWithSemanticErrors; - } - else if (resolver.hasSemanticErrors() && compilerOptions.declaration) { - // There is an semantic errror when output javascript and declaration file - // Output JS file with semantic error, not output declaration file - returnCode = EmitReturnStatus.DeclarationGenerationSkipped; - } - else if (hasEmitterError) { + if (hasEmitterError) { returnCode = EmitReturnStatus.EmitErrorsEncountered; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 70c02cf594f..100c966248d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -612,7 +612,7 @@ module ts { getSymbolCount(): number; getTypeCount(): number; checkProgram(): void; - emitFiles(): EmitResult; + emitFiles(targetSourceFile?: SourceFile): EmitResult; getParentOfSymbol(symbol: Symbol): Symbol; getTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; @@ -671,7 +671,6 @@ module ts { getNodeCheckFlags(node: Node): NodeCheckFlags; getEnumMemberValue(node: EnumMember): number; hasSemanticErrors(): boolean; - shouldEmitDeclarations(): boolean; isDeclarationVisible(node: Declaration): boolean; isImplementationOfOverload(node: FunctionDeclaration): boolean; writeTypeAtLocation(location: Node, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: TextWriter): void; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index de789680284..30deb174e46 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -122,49 +122,41 @@ module FourSlash { return s.replace(/[&<>"'\/]/g, ch => entityMap[ch]); } - // Name of ts.CompilerOptions properties that will be used by globalOptions - // To add additional option, add property into the compilerOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames + // Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions + // To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames // Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data - var compilerOptMetadataNames = { - out: 'out', - outDir: 'outDir', - declaration: 'declaration', - sourceMap: 'sourceMap', - sourceRoot: 'sourceRoot', - mapRoot: 'mapRoot', - module: 'module', + var testOptMetadataNames = { + baselineFile: 'BaselineFile', + declaration: 'declaration', + emitThisFile: 'emitThisFile', // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project + filename: 'Filename', + mapRoot: 'mapRoot', + module: 'module', + out: 'out', + outDir: 'outDir', + sourceMap: 'sourceMap', + sourceRoot: 'sourceRoot', }; // List of allowed metadata names - var fileMetadataNames = ['Filename']; - var globalMetadataNames = ['BaselineFile', compilerOptMetadataNames.out, compilerOptMetadataNames.outDir, compilerOptMetadataNames.declaration, compilerOptMetadataNames.outDir, - compilerOptMetadataNames.declaration, compilerOptMetadataNames.sourceMap, compilerOptMetadataNames.sourceRoot, compilerOptMetadataNames.mapRoot, compilerOptMetadataNames.module] + var fileMetadataNames = [testOptMetadataNames.filename, testOptMetadataNames.emitThisFile]; + var globalMetadataNames = [testOptMetadataNames.baselineFile, testOptMetadataNames.declaration, + testOptMetadataNames.mapRoot, testOptMetadataNames.module, testOptMetadataNames.out, + testOptMetadataNames.outDir, testOptMetadataNames.sourceMap, testOptMetadataNames.sourceRoot] function convertGlobalOptionsToCompilationSettings(globalOptions: { [idx: string]: string }): ts.CompilationSettings { var settings: ts.CompilationSettings = {}; - // Convert all property in globalOptions into ts.CompilationSettings + // Convert all property in globalOptions into ts.CompilationSettings for (var prop in globalOptions) { if (globalOptions.hasOwnProperty(prop)) { switch (prop) { - case compilerOptMetadataNames.out: - settings.outFileOption = globalOptions[prop]; - break; - case compilerOptMetadataNames.outDir: - settings.outDirOption = globalOptions[prop]; - break; - case compilerOptMetadataNames.declaration: - settings.generateDeclarationFiles = true; - break; - case compilerOptMetadataNames.sourceMap: - settings.mapSourceFiles = true; - break; - case compilerOptMetadataNames.sourceRoot: - settings.sourceRoot = globalOptions[prop]; - break; - case compilerOptMetadataNames.mapRoot: - settings.mapRoot = globalOptions[prop]; - break; - case compilerOptMetadataNames.module: + case testOptMetadataNames.declaration: + settings.generateDeclarationFiles = true; + break; + case testOptMetadataNames.mapRoot: + settings.mapRoot = globalOptions[prop]; + break; + case testOptMetadataNames.module: // create appropriate external module target for CompilationSettings switch (globalOptions[prop]) { case "AMD": @@ -177,7 +169,20 @@ module FourSlash { settings.moduleGenTarget = ts.ModuleGenTarget.Unspecified; break; } - break; + break; + case testOptMetadataNames.out: + settings.outFileOption = globalOptions[prop]; + break; + case testOptMetadataNames.outDir: + settings.outDirOption = globalOptions[prop]; + break; + case testOptMetadataNames.sourceMap: + settings.mapSourceFiles = true; + break; + case testOptMetadataNames.sourceRoot: + settings.sourceRoot = globalOptions[prop]; + break; + } } } @@ -938,7 +943,7 @@ module FourSlash { Harness.Baseline.runBaseline( "Breakpoint Locations for " + this.activeFile.fileName, - this.testData.globalOptions['BaselineFile'], + this.testData.globalOptions[testOptMetadataNames.baselineFile], () => { var fileLength = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getLength(); var resultString = ""; @@ -951,47 +956,61 @@ module FourSlash { } public baselineGetEmitOutput() { - this.taoInvalidReason = 'baselineCurrentFileBreakpointLocations impossible'; + this.taoInvalidReason = 'baselineGetEmitOutput impossible'; + // Find file to be emitted + var emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on + + var allFourSlashFiles = this.testData.files; + for (var idx = 0; idx < allFourSlashFiles.length; ++idx) { + var file = allFourSlashFiles[idx]; + if (file.fileOptions[testOptMetadataNames.emitThisFile]) { + // Find a file with the flag emitThisFile turned on + emitFiles.push(file); + } + } + + // If there is not emiThisFile flag specified in the test file, throw an error + if (emitFiles.length === 0) { + throw new Error("No emitThisFile is specified in the test file"); + } Harness.Baseline.runBaseline( - "Breakpoint Locations for " + this.activeFile.fileName, - this.testData.globalOptions['BaselineFile'], + "Generate getEmitOutput baseline : " + emitFiles.join(" "), + this.testData.globalOptions[testOptMetadataNames.baselineFile], () => { - var emitOutput = this.languageService.getEmitOutput(this.activeFile.fileName); - var emitOutputStatus = emitOutput.emitOutputStatus; var resultString = ""; + // Loop through all the emittedFiles and emit them one by one + emitFiles.forEach(emitFile => { + var emitOutput = this.languageService.getEmitOutput(emitFile.fileName); + var emitOutputStatus = emitOutput.emitOutputStatus; - // Print emitOutputStatus in readable format - switch (emitOutputStatus) { - case ts.EmitReturnStatus.Succeeded: - resultString += "EmitOutputStatus : Succeeded\n"; - break; - case ts.EmitReturnStatus.AllOutputGenerationSkipped: - resultString += "EmitOutputStatus : AllOutputGenerationSkipped\n"; - break; - case ts.EmitReturnStatus.JSGeneratedWithSemanticErrors: - resultString += "EmitOutputStatus : JSGeneratedWithSemanticErrors\n"; - break; - case ts.EmitReturnStatus.DeclarationGenerationSkipped: - resultString += "EmitOutputStatus : DeclaratiionGenerationSkipped\n"; - break; - case ts.EmitReturnStatus.EmitErrorsEncountered: - resultString += "EmitOutputStatus : EmitErrorEncountered\n"; - break; - default: - resultString += "Invalid EmitOutputStatus\n"; - break; - } + // Print emitOutputStatus in readable format + switch (emitOutputStatus) { + case ts.EmitReturnStatus.Succeeded: + resultString += "EmitOutputStatus : Succeeded\n"; + break; + case ts.EmitReturnStatus.AllOutputGenerationSkipped: + resultString += "EmitOutputStatus : AllOutputGenerationSkipped\n"; + break; + case ts.EmitReturnStatus.JSGeneratedWithSemanticErrors: + resultString += "EmitOutputStatus : JSGeneratedWithSemanticErrors\n"; + break; + case ts.EmitReturnStatus.DeclarationGenerationSkipped: + resultString += "EmitOutputStatus : DeclaratiionGenerationSkipped\n"; + break; + case ts.EmitReturnStatus.EmitErrorsEncountered: + resultString += "EmitOutputStatus : EmitErrorEncountered\n"; + break; + default: + resultString += "Invalid EmitOutputStatus\n"; + break; + } - emitOutput.outputFiles.forEach((outputFile, idx, array) => { - var filename = "Filename : " + outputFile.name + "\n"; - if (filename.match("/*.js.map/") === undefined) { - var content = outputFile.text; - } - else { - var content = outputFile.text + "\n"; - } - resultString = resultString + filename + content + "\n"; + emitOutput.outputFiles.forEach((outputFile, idx, array) => { + var filename = "Filename : " + outputFile.name + "\n"; + resultString = resultString + filename + outputFile.text; + }); + resultString += "\n"; }); return resultString; }, @@ -1522,7 +1541,7 @@ module FourSlash { Harness.Baseline.runBaseline( "Name OrDottedNameSpans for " + this.activeFile.fileName, - this.testData.globalOptions['BaselineFile'], + this.testData.globalOptions[testOptMetadataNames.baselineFile], () => { var fileLength = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getLength(); var resultString = ""; @@ -2123,12 +2142,12 @@ module FourSlash { // Comment line, check for global/file @options and record them var match = optionRegex.exec(line.substr(2)); if (match) { - var globalNameIndex = globalMetadataNames.indexOf(match[1]); - var fileNameIndex = fileMetadataNames.indexOf(match[1]); - if (globalNameIndex === -1) { - if (fileNameIndex === -1) { + var globalMetadataNamesIndex = globalMetadataNames.indexOf(match[1]); + var fileMetadataNamesIndex = fileMetadataNames.indexOf(match[1]); + if (globalMetadataNamesIndex === -1) { + if (fileMetadataNamesIndex === -1) { throw new Error('Unrecognized metadata name "' + match[1] + '". Available global metadata names are: ' + globalMetadataNames.join(', ') + '; file metadata names are: ' + fileMetadataNames.join(', ')); - } else { + } else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(testOptMetadataNames.filename)) { // Found an @Filename directive, if this is not the first then create a new subfile if (currentFileContent) { var file = parseFileContent(currentFileContent, currentFileName, markerMap, markers, ranges); @@ -2145,6 +2164,9 @@ module FourSlash { currentFileName = 'tests/cases/fourslash/' + match[2]; currentFileOptions[match[1]] = match[2]; + } else { + // Add other fileMetadata flag + currentFileOptions[match[1]] = match[2]; } } else { // Check if the match is already existed in the global options diff --git a/src/services/services.ts b/src/services/services.ts index a110a4b9635..cc45e861946 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2837,9 +2837,9 @@ module ts { function getEmitOutput(filename: string): EmitOutput { synchronizeHostData(); filename = TypeScript.switchToForwardSlashes(filename); - var sourceFile = program.getSourceFile(filename); var compilerOptions = program.getCompilerOptions(); - var emitToSingleFile = ts.shouldEmitToOwnFile(sourceFile, compilerOptions); + var targetSourceFile = program.getSourceFile(filename); // Current selected file to be output + var emitToSingleFile = ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions); var emitDeclaration = compilerOptions.declaration; var emitOutput: EmitOutput = { outputFiles: [], @@ -2855,10 +2855,20 @@ module ts { }); } - var syntacticDiagnostics = emitToSingleFile - ? program.getDiagnostics(sourceFile) - : program.getDiagnostics(); - var globalSyntacticDiagnostics = program.getGlobalDiagnostics(); + var syntacticDiagnostics: Diagnostic[] = []; + if (emitToSingleFile) { + // Check only the file we want to emit + syntacticDiagnostics = program.getDiagnostics(targetSourceFile); + } + else { + // Only check the syntactic of only sourceFiles that will get emitted into single output + forEach(program.getSourceFiles(), sourceFile => { + // Emit to a single file then we will check all files that do not have external module + if (!isExternalModuleOrDeclarationFile(sourceFile)) { + syntacticDiagnostics = syntacticDiagnostics.concat(program.getDiagnostics(sourceFile)); + } + }); + } // If there is any syntactic error, terminate the process if (containErrors(syntacticDiagnostics)) { @@ -2868,7 +2878,15 @@ module ts { // Perform semantic and force a type check before emit to ensure that all symbols are updated // EmitFiles will report if there is an error from TypeChecker and Emitter - var emitFilesResult = getFullTypeCheckChecker().emitFiles(); + if (emitToSingleFile) { + // Emit only selected file in the project + var emitFilesResult = getFullTypeCheckChecker().emitFiles(targetSourceFile); + } + else { + // Emit all files into single file + var emitFilesResult = getFullTypeCheckChecker().emitFiles(); + } + emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus; // Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput diff --git a/tests/cases/fourslash/fourslash.d.ts b/tests/cases/fourslash/fourslash.d.ts deleted file mode 100644 index b3ad5e000db..00000000000 --- a/tests/cases/fourslash/fourslash.d.ts +++ /dev/null @@ -1,179 +0,0 @@ -declare var FourSlash: any; -declare enum IncrementalEditValidation { - None, - SyntacticOnly, - Complete, -} -declare enum TypingFidelity { - /** Performs typing and formatting (if formatting is enabled) */ - Low, - /** Performs typing, checks completion lists, signature help, and formatting (if enabled) */ - High, -} -declare enum EmitReturnStatus { - Succeeded = 0, - AllOutputGenerationSkipped = 1, - JSGeneratedWithSemanticErrors = 2, - DeclarationGenerationSkipped = 3, - EmitErrorsEncountered = 4, -} -declare module FourSlashInterface { - interface Marker { - fileName: string; - position: number; - data?: any; - } - interface Range { - fileName: string; - start: number; - end: number; - marker?: Marker; - } - interface TextSpan { - start: number; - end: number; - } - class test_ { - markers(): Marker[]; - ranges(): Range[]; - } - class diagnostics { - validateTypeAtCurrentPosition(): any; - validateTypesAtPositions(...positions: number[]): any; - setEditValidation(validation: IncrementalEditValidation): void; - setTypingFidelity(fidelity: TypingFidelity): void; - } - class goTo { - marker(name?: string): void; - bof(): void; - eof(): void; - definition(definitionIndex?: number): void; - position(position: number, fileIndex?: number): any; - position(position: number, fileName?: string): any; - file(index: number): any; - file(name: string): any; - } - class verifyNegatable { - private negative; - not: verifyNegatable; - constructor(negative?: boolean); - memberListContains(symbol: string, type?: string, docComment?: string, fullSymbolName?: string, kind?: string): void; - memberListCount(expectedCount: number): void; - completionListContains(symbol: string, type?: string, docComment?: string, fullSymbolName?: string, kind?: string): void; - completionListItemsCountIsGreaterThan(count: number): void; - completionListIsEmpty(): void; - memberListIsEmpty(): void; - referencesCountIs(count: number): void; - referencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; - implementorsCountIs(count: number): void; - currentParameterIsVariable(): void; - signatureHelpPresent(): void; - errorExistsBetweenMarkers(startMarker: string, endMarker: string): void; - errorExistsAfterMarker(markerName?: string): void; - errorExistsBeforeMarker(markerName?: string): void; - quickInfoIs(typeName?: string, docComment?: string, symbolName?: string, kind?: string): void; - quickInfoSymbolNameIs(symbolName: any): void; - quickInfoExists(): void; - definitionLocationExists(): void; - } - class verify extends verifyNegatable { - caretAtMarker(markerName?: string): void; - indentationIs(numberOfSpaces: number): void; - indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number): void; - textAtCaretIs(text: string): void; - /** - Compiles the current file and evaluates 'expr' in a context containing - the emitted output, then compares (using ===) the result of that expression - to 'value'. Do not use this function with external modules as it is not supported. - */ - eval(expr: string, value: any): void; - emitOutput(expectedState: EmitReturnStatus, expectedFilename?: string): void; - currentLineContentIs(text: string): void; - currentFileContentIs(text: string): void; - currentParameterHelpArgumentNameIs(name: string): void; - currentParameterSpanIs(parameter: string): void; - currentParameterHelpArgumentDocCommentIs(docComment: string): void; - currentSignatureHelpDocCommentIs(docComment: string): void; - signatureHelpCountIs(expected: number): void; - currentSignatureParamterCountIs(expected: number): void; - currentSignatureTypeParamterCountIs(expected: number): void; - currentSignatureHelpIs(expected: string): void; - numberOfErrorsInCurrentFile(expected: number): void; - baselineCurrentFileBreakpointLocations(): void; - baselineCurrentFileNameOrDottedNameSpans(): void; - nameOrDottedNameSpanTextIs(text: string): void; - outliningSpansInCurrentFile(spans: TextSpan[]): void; - todoCommentsInCurrentFile(descriptors: string[]): void; - matchingBracePositionInCurrentFile(bracePosition: number, expectedMatchPosition: number): void; - noMatchingBracePositionInCurrentFile(bracePosition: number): void; - setVerifyDocComments(val: boolean): void; - getScriptLexicalStructureListCount(count: number): void; - getScriptLexicalStructureListContains(name: string, kind: string, fileName?: string, parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number): void; - navigationItemsListCount(count: number, searchValue: string, matchKind?: string): void; - navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parenetName?: string): void; - occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; - occurrencesAtPositionCount(expectedCount: number): void; - completionEntryDetailIs(entryName: string, type: string, docComment?: string, fullSymbolName?: string, kind?: string): void; - } - class edit { - backspace(count?: number): void; - deleteAtCaret(times?: number): void; - replace(start: number, length: number, text: string): void; - paste(text: string): void; - insert(text: string): void; - insertLine(text: string): void; - insertLines(...lines: string[]): void; - moveRight(count?: number): void; - moveLeft(count?: number): void; - enableFormatting(): void; - disableFormatting(): void; - } - class debug { - printCurrentParameterHelp(): void; - printCurrentFileState(): void; - printCurrentFileStateWithWhitespace(): void; - printCurrentFileStateWithoutCaret(): void; - printCurrentQuickInfo(): void; - printCurrentSignatureHelp(): void; - printMemberListMembers(): void; - printCompletionListMembers(): void; - printBreakpointLocation(pos: number): void; - printBreakpointAtCurrentLocation(): void; - printNameOrDottedNameSpans(pos: number): void; - printErrorList(): void; - printNavigationItems(searchValue?: string): void; - printScriptLexicalStructureItems(): void; - printReferences(): void; - printContext(): void; - } - class format { - document(): void; - selection(startMarker: string, endMarker: string): void; - setOption(name: string, value: number): any; - setOption(name: string, value: string): any; - setOption(name: string, value: boolean): any; - } - class cancellation { - resetCancelled(): void; - setCancelled(numberOfCalls?: number): void; - } -} -declare module fs { - var test: FourSlashInterface.test_; - var goTo: FourSlashInterface.goTo; - var verify: FourSlashInterface.verify; - var edit: FourSlashInterface.edit; - var debug: FourSlashInterface.debug; - var format: FourSlashInterface.format; - var diagnostics: FourSlashInterface.diagnostics; - var cancellation: FourSlashInterface.cancellation; -} -declare function verifyOperationIsCancelled(f: any): void; -declare var test: FourSlashInterface.test_; -declare var goTo: FourSlashInterface.goTo; -declare var verify: FourSlashInterface.verify; -declare var edit: FourSlashInterface.edit; -declare var debug: FourSlashInterface.debug; -declare var format: FourSlashInterface.format; -declare var diagnostics: FourSlashInterface.diagnostics; -declare var cancellation: FourSlashInterface.cancellation; diff --git a/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts b/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts index 942a48a4c73..b9c7f5a0db9 100644 --- a/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts +++ b/tests/cases/fourslash/getEmitOutputDeclarationMultiFiles.ts @@ -2,7 +2,9 @@ // @BaselineFile: getEmitOutputDeclarationMultiFiles.baseline // @declaration: true + // @Filename: inputFile1.ts +// @emitThisFile: true //// var x: number = 5; //// class Bar { //// x : string; @@ -10,6 +12,7 @@ //// } // @Filename: inputFile2.ts +// @emitThisFile: true //// var x1: string = "hello world"; //// class Foo{ //// x : string; diff --git a/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts b/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts index 788519d0eab..b8e9c58f5b0 100644 --- a/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts +++ b/tests/cases/fourslash/getEmitOutputDeclarationSingleFile.ts @@ -2,8 +2,10 @@ // @BaselineFile: getEmitOutputDeclarationSingleFile.baseline // @declaration: true -// @Filename: inputFile1.ts // @out: declSingleFile.js + +// @Filename: inputFile1.ts +// @emitThisFile: true //// var x: number = 5; //// class Bar { //// x : string; diff --git a/tests/cases/fourslash/getEmitOutputMapRoot.ts b/tests/cases/fourslash/getEmitOutputMapRoot.ts index 439c1e20372..15932d41c32 100644 --- a/tests/cases/fourslash/getEmitOutputMapRoot.ts +++ b/tests/cases/fourslash/getEmitOutputMapRoot.ts @@ -1,9 +1,12 @@ /// // @BaselineFile: getEmitOutputMapRoots.baseline -// @Filename: inputFile.ts +// @out: declSingleFile.js // @sourceMap: true // @mapRoot: mapRootDir/ + +// @Filename: inputFile.ts +// @emitThisFile: true //// var x = 109; //// var foo = "hello world"; //// class M { diff --git a/tests/cases/fourslash/getEmitOutputNoErrors.ts b/tests/cases/fourslash/getEmitOutputNoErrors.ts index 955b1b77034..b48a86a03ab 100644 --- a/tests/cases/fourslash/getEmitOutputNoErrors.ts +++ b/tests/cases/fourslash/getEmitOutputNoErrors.ts @@ -2,6 +2,7 @@ // @BaselineFile: getEmitOutputNoErrors.baseline // @Filename: inputFile.ts +// @emitThisFile: true //// var x; //// class M { //// x: number; diff --git a/tests/cases/fourslash/getEmitOutputOnlyOneFile.ts b/tests/cases/fourslash/getEmitOutputOnlyOneFile.ts new file mode 100644 index 00000000000..2ad822741f2 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputOnlyOneFile.ts @@ -0,0 +1,20 @@ +/// + +// @BaselineFile: getEmitOutputOnlyOneFile.baseline + +// @Filename: inputFile1.ts +//// var x: any; +//// class Bar { +//// x : string; +//// y : number +//// } + +// @Filename: inputFile2.ts +// @emitThisFile: true +//// var x: any; +//// class Foo{ +//// x : string; +//// y : number +//// } + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSingleFile.ts b/tests/cases/fourslash/getEmitOutputSingleFile.ts index eccb8ce5cb5..ec774149f4b 100644 --- a/tests/cases/fourslash/getEmitOutputSingleFile.ts +++ b/tests/cases/fourslash/getEmitOutputSingleFile.ts @@ -2,6 +2,7 @@ // @BaselineFile: getEmitOutputSingleFile.baseline // @out: outputDir/singleFile.js + // @Filename: inputFile1.ts //// var x: any; //// class Bar { @@ -10,6 +11,7 @@ //// } // @Filename: inputFile2.ts +// @emitThisFile: true //// var x: any; //// class Foo{ //// x : string; diff --git a/tests/cases/fourslash/getEmitOutputSingleFile2.ts b/tests/cases/fourslash/getEmitOutputSingleFile2.ts index c54ad22cc4f..bcb1012a6ea 100644 --- a/tests/cases/fourslash/getEmitOutputSingleFile2.ts +++ b/tests/cases/fourslash/getEmitOutputSingleFile2.ts @@ -2,9 +2,10 @@ // @BaselineFile: getEmitOutputSingleFile2.baseline // @declaration: true -// @Filename: inputFile1.ts // @out: declSingleFile.js // @outDir: tests/cases/fourslash/ + +// @Filename: inputFile1.ts //// var x: number = 5; //// class Bar { //// x : string; @@ -19,14 +20,8 @@ //// } // @Filename: inputFile3.ts +// @emitThisFile: true ////export var foo = 10; ////export var bar = "hello world" -var singleFilename = "declSingleFile"; -var jsFilename = singleFilename + ".js"; -var declFilename = singleFilename + ".d.ts"; -var exportFilename = "tests/cases/fourslash/inputFile3" -var exportJSFilename = exportFilename + ".js"; -var exportDeclFilename = exportFilename + ".d.ts"; -var outputFilenames = jsFilename + " " + declFilename + " " + exportJSFilename + " " + exportDeclFilename; verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputSourceMap.ts b/tests/cases/fourslash/getEmitOutputSourceMap.ts index 753ac77a29a..df02af35ec3 100644 --- a/tests/cases/fourslash/getEmitOutputSourceMap.ts +++ b/tests/cases/fourslash/getEmitOutputSourceMap.ts @@ -2,7 +2,9 @@ // @BaselineFile: getEmitOutputSourceMap.baseline // @sourceMap: true + // @Filename: inputFile.ts +// @emitThisFile: true //// var x = 109; //// var foo = "hello world"; //// class M { diff --git a/tests/cases/fourslash/getEmitOutputSourceMap2.ts b/tests/cases/fourslash/getEmitOutputSourceMap2.ts index b3977095b82..a8b43328ea5 100644 --- a/tests/cases/fourslash/getEmitOutputSourceMap2.ts +++ b/tests/cases/fourslash/getEmitOutputSourceMap2.ts @@ -2,8 +2,10 @@ // @BaselineFile: getEmitOutputSourceMap2.baseline // @sourceMap: true -// @Filename: inputFile1.ts // @outDir: sample/outDir + +// @Filename: inputFile1.ts +// @emitThisFile: true //// var x = 109; //// var foo = "hello world"; //// class M { @@ -12,6 +14,7 @@ //// } // @Filename: inputFile2.ts +// @emitThisFile: true //// var intro = "hello world"; //// if (intro !== undefined) { //// var k = 10; diff --git a/tests/cases/fourslash/getEmitOutputSourceRoot.ts b/tests/cases/fourslash/getEmitOutputSourceRoot.ts index c71015c17aa..b260e593098 100644 --- a/tests/cases/fourslash/getEmitOutputSourceRoot.ts +++ b/tests/cases/fourslash/getEmitOutputSourceRoot.ts @@ -2,8 +2,10 @@ // @BaselineFile: getEmitOutputSourceRoot.baseline // @sourceMap: true -// @Filename: inputFile.ts // @sourceRoot: sourceRootDir/ + +// @Filename: inputFile.ts +// @emitThisFile: true //// var x = 109; //// var foo = "hello world"; //// class M { diff --git a/tests/cases/fourslash/getEmitOutputSourceRoot2.ts b/tests/cases/fourslash/getEmitOutputSourceRootMultiFiles.ts similarity index 84% rename from tests/cases/fourslash/getEmitOutputSourceRoot2.ts rename to tests/cases/fourslash/getEmitOutputSourceRootMultiFiles.ts index 1596269ed67..bddf9e423ce 100644 --- a/tests/cases/fourslash/getEmitOutputSourceRoot2.ts +++ b/tests/cases/fourslash/getEmitOutputSourceRootMultiFiles.ts @@ -1,9 +1,11 @@ /// // @BaselineFile: getEmitOutputSourceRootMultiFiles.baseline -// @Filename: inputFile1.ts // @sourceMap: true // @sourceRoot: sourceRootDir/ + +// @Filename: inputFile1.ts +// @emitThisFile: true //// var x = 109; //// var foo = "hello world"; //// class M { @@ -12,6 +14,7 @@ //// } // @Filename: inputFile2.ts +// @emitThisFile: true //// var bar = "hello world Typescript"; //// class C { //// x: number; diff --git a/tests/cases/fourslash/getEmitOutputWithEmitterErrors.ts b/tests/cases/fourslash/getEmitOutputWithEmitterErrors.ts index 78ab635a137..ba643f996d7 100644 --- a/tests/cases/fourslash/getEmitOutputWithEmitterErrors.ts +++ b/tests/cases/fourslash/getEmitOutputWithEmitterErrors.ts @@ -2,7 +2,9 @@ // @BaselineFile: getEmitOutputWithEmitterErrors.baseline // @declaration: true + // @Filename: inputFile.ts +// @emitThisFile: true ////module M { //// class C { } //// export var foo = new C(); diff --git a/tests/cases/fourslash/getEmitOutputWithEmitterErrors2.ts b/tests/cases/fourslash/getEmitOutputWithEmitterErrors2.ts index 3a168143b83..5240a102a28 100644 --- a/tests/cases/fourslash/getEmitOutputWithEmitterErrors2.ts +++ b/tests/cases/fourslash/getEmitOutputWithEmitterErrors2.ts @@ -3,7 +3,9 @@ // @BaselineFile: getEmitOutputWithEmitterErrors2.baseline // @declaration: true // @module: AMD + // @Filename: inputFile.ts +// @emitThisFile: true ////class C { } ////export module M { //// export var foo = new C(); diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts index 9388148954f..b4e3a50b0e8 100644 --- a/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrors.ts @@ -1,7 +1,9 @@ /// // @BaselineFile: getEmitOutputWithSemanticErrors.baseline + // @Filename: inputFile.ts +// @emitThisFile: true //// var x:number = "hello world"; verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts index 5499f979b50..c67ef0fd29d 100644 --- a/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrors2.ts @@ -2,7 +2,9 @@ // @BaselineFile: getEmitOutputWithSemanticErrors2.baseline // @declaration: true + // @Filename: inputFile.ts +// @emitThisFile: true //// var x:number = "hello world"; verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts index 81631b3d4d0..87e9bb076a5 100644 --- a/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts +++ b/tests/cases/fourslash/getEmitOutputWithSyntaxErrors.ts @@ -1,7 +1,9 @@ /// // @BaselineFile: getEmitOutputWithSyntaxErrors.baseline + // @Filename: inputFile.ts +// @emitThisFile: true //// var x: verify.baselineGetEmitOutput(); \ No newline at end of file From 2ad20d2e6b6aed06a6a4c16de9ae2f7725853395 Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 12 Sep 2014 13:19:26 -0700 Subject: [PATCH 27/34] Fix declaring function for writer and setting writer to undefined --- src/services/services.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index cc45e861946..f3e309615ae 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2830,8 +2830,7 @@ module ts { } function containErrors(diagnostics: Diagnostic[]): boolean { - var hasError = forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); - return hasError; + return forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); } function getEmitOutput(filename: string): EmitOutput { @@ -2846,15 +2845,17 @@ module ts { emitOutputStatus: undefined, }; - // Initialize writer for CompilerHost.writeFile - writer = function (fileName: string, data: string, writeByteOrderMark: boolean) { + function getEmitOutputWriter(filename: string, data: string, writeByteOrderMark: boolean) { emitOutput.outputFiles.push({ - name: fileName, + name: filename, writeByteOrderMark: writeByteOrderMark, text: data }); } + // Initialize writer for CompilerHost.writeFile + writer = getEmitOutputWriter; + var syntacticDiagnostics: Diagnostic[] = []; if (emitToSingleFile) { // Check only the file we want to emit @@ -2873,6 +2874,8 @@ module ts { // If there is any syntactic error, terminate the process if (containErrors(syntacticDiagnostics)) { emitOutput.emitOutputStatus = EmitReturnStatus.AllOutputGenerationSkipped; + // Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput + writer = undefined; return emitOutput; } @@ -2890,7 +2893,7 @@ module ts { emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus; // Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput - this.writer = undefined; + writer = undefined; return emitOutput; } From 13cf339fddbd7ec7337918cfc67f9a1e1707e991 Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 12 Sep 2014 13:20:10 -0700 Subject: [PATCH 28/34] Add getEmitOutput baselines --- ...etEmitOutputDeclarationMultiFiles.baseline | 30 +++++++++++++++++ ...etEmitOutputDeclarationSingleFile.baseline | 26 +++++++++++++++ .../reference/getEmitOutputMapRoots.baseline | 11 +++++++ .../reference/getEmitOutputNoErrors.baseline | 9 ++++++ .../getEmitOutputOnlyOneFile.baseline | 9 ++++++ .../getEmitOutputSingleFile.baseline | 15 +++++++++ .../getEmitOutputSingleFile2.baseline | 32 +++++++++++++++++++ .../reference/getEmitOutputSourceMap.baseline | 11 +++++++ .../getEmitOutputSourceMap2.baseline | 19 +++++++++++ .../getEmitOutputSourceRoot.baseline | 11 +++++++ ...getEmitOutputSourceRootMultiFiles.baseline | 21 ++++++++++++ .../getEmitOutputWithEmitterErrors.baseline | 12 +++++++ .../getEmitOutputWithEmitterErrors2.baseline | 14 ++++++++ .../getEmitOutputWithSemanticErrors.baseline | 4 +++ .../getEmitOutputWithSemanticErrors2.baseline | 4 +++ .../getEmitOutputWithSyntaxErrors.baseline | 2 ++ 16 files changed, 230 insertions(+) create mode 100644 tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline create mode 100644 tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline create mode 100644 tests/baselines/reference/getEmitOutputMapRoots.baseline create mode 100644 tests/baselines/reference/getEmitOutputNoErrors.baseline create mode 100644 tests/baselines/reference/getEmitOutputOnlyOneFile.baseline create mode 100644 tests/baselines/reference/getEmitOutputSingleFile.baseline create mode 100644 tests/baselines/reference/getEmitOutputSingleFile2.baseline create mode 100644 tests/baselines/reference/getEmitOutputSourceMap.baseline create mode 100644 tests/baselines/reference/getEmitOutputSourceMap2.baseline create mode 100644 tests/baselines/reference/getEmitOutputSourceRoot.baseline create mode 100644 tests/baselines/reference/getEmitOutputSourceRootMultiFiles.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithSemanticErrors.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithSyntaxErrors.baseline diff --git a/tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline b/tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline new file mode 100644 index 00000000000..6aec1296d81 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputDeclarationMultiFiles.baseline @@ -0,0 +1,30 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile1.js +var x = 5; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +Filename : tests/cases/fourslash/inputFile1.d.ts +declare var x: number; +declare class Bar { + x: string; + y: number; +} + +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile2.js +var x1 = "hello world"; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); +Filename : tests/cases/fourslash/inputFile2.d.ts +declare var x1: string; +declare class Foo { + x: string; + y: number; +} + diff --git a/tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline b/tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline new file mode 100644 index 00000000000..ba40a69e39d --- /dev/null +++ b/tests/baselines/reference/getEmitOutputDeclarationSingleFile.baseline @@ -0,0 +1,26 @@ +EmitOutputStatus : Succeeded +Filename : declSingleFile.js +var x = 5; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +var x1 = "hello world"; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); +Filename : declSingleFile.d.ts +declare var x: number; +declare class Bar { + x: string; + y: number; +} +declare var x1: string; +declare class Foo { + x: string; + y: number; +} + diff --git a/tests/baselines/reference/getEmitOutputMapRoots.baseline b/tests/baselines/reference/getEmitOutputMapRoots.baseline new file mode 100644 index 00000000000..2630257b03a --- /dev/null +++ b/tests/baselines/reference/getEmitOutputMapRoots.baseline @@ -0,0 +1,11 @@ +EmitOutputStatus : Succeeded +Filename : declSingleFile.js.map +{"version":3,"file":"declSingleFile.js","sourceRoot":"","sources":["../tests/cases/fourslash/inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : declSingleFile.js +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); +//# sourceMappingURL=mapRootDir/declSingleFile.js.map diff --git a/tests/baselines/reference/getEmitOutputNoErrors.baseline b/tests/baselines/reference/getEmitOutputNoErrors.baseline new file mode 100644 index 00000000000..000ddb29ef5 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputNoErrors.baseline @@ -0,0 +1,9 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile.js +var x; +var M = (function () { + function M() { + } + return M; +})(); + diff --git a/tests/baselines/reference/getEmitOutputOnlyOneFile.baseline b/tests/baselines/reference/getEmitOutputOnlyOneFile.baseline new file mode 100644 index 00000000000..eaca7cda673 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputOnlyOneFile.baseline @@ -0,0 +1,9 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile2.js +var x; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); + diff --git a/tests/baselines/reference/getEmitOutputSingleFile.baseline b/tests/baselines/reference/getEmitOutputSingleFile.baseline new file mode 100644 index 00000000000..fd3d2af4a5a --- /dev/null +++ b/tests/baselines/reference/getEmitOutputSingleFile.baseline @@ -0,0 +1,15 @@ +EmitOutputStatus : Succeeded +Filename : outputDir/singleFile.js +var x; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +var x; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); + diff --git a/tests/baselines/reference/getEmitOutputSingleFile2.baseline b/tests/baselines/reference/getEmitOutputSingleFile2.baseline new file mode 100644 index 00000000000..aac50ee87cb --- /dev/null +++ b/tests/baselines/reference/getEmitOutputSingleFile2.baseline @@ -0,0 +1,32 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile3.js +exports.foo = 10; +exports.bar = "hello world"; +Filename : tests/cases/fourslash/inputFile3.d.ts +export declare var foo: number; +export declare var bar: string; +Filename : declSingleFile.js +var x = 5; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +var x1 = "hello world"; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); +Filename : declSingleFile.d.ts +declare var x: number; +declare class Bar { + x: string; + y: number; +} +declare var x1: string; +declare class Foo { + x: string; + y: number; +} + diff --git a/tests/baselines/reference/getEmitOutputSourceMap.baseline b/tests/baselines/reference/getEmitOutputSourceMap.baseline new file mode 100644 index 00000000000..e3b7a47e125 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputSourceMap.baseline @@ -0,0 +1,11 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile.js.map +{"version":3,"file":"inputFile.js","sourceRoot":"","sources":["inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile.js +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); +//# sourceMappingURL=inputFile.js.map diff --git a/tests/baselines/reference/getEmitOutputSourceMap2.baseline b/tests/baselines/reference/getEmitOutputSourceMap2.baseline new file mode 100644 index 00000000000..d6745389e3a --- /dev/null +++ b/tests/baselines/reference/getEmitOutputSourceMap2.baseline @@ -0,0 +1,19 @@ +EmitOutputStatus : Succeeded +Filename : sample/outDir/inputFile1.js.map +{"version":3,"file":"inputFile1.js","sourceRoot":"","sources":["../../tests/cases/fourslash/inputFile1.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : sample/outDir/inputFile1.js +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); +//# sourceMappingURL=inputFile1.js.map +EmitOutputStatus : Succeeded +Filename : sample/outDir/inputFile2.js.map +{"version":3,"file":"inputFile2.js","sourceRoot":"","sources":["../../tests/cases/fourslash/inputFile2.ts"],"names":[],"mappings":"AAAA,IAAI,KAAK,GAAG,aAAa,CAAC;AAC1B,EAAE,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG,EAAE,CAAC;AACd,CAAC"}Filename : sample/outDir/inputFile2.js +var intro = "hello world"; +if (intro !== undefined) { + var k = 10; +} +//# sourceMappingURL=inputFile2.js.map diff --git a/tests/baselines/reference/getEmitOutputSourceRoot.baseline b/tests/baselines/reference/getEmitOutputSourceRoot.baseline new file mode 100644 index 00000000000..d8cba7ddd97 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputSourceRoot.baseline @@ -0,0 +1,11 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile.js.map +{"version":3,"file":"inputFile.js","sourceRoot":"sourceRootDir/","sources":["inputFile.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile.js +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); +//# sourceMappingURL=inputFile.js.map diff --git a/tests/baselines/reference/getEmitOutputSourceRootMultiFiles.baseline b/tests/baselines/reference/getEmitOutputSourceRootMultiFiles.baseline new file mode 100644 index 00000000000..eec0b05ecaa --- /dev/null +++ b/tests/baselines/reference/getEmitOutputSourceRootMultiFiles.baseline @@ -0,0 +1,21 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile1.js.map +{"version":3,"file":"inputFile1.js","sourceRoot":"sourceRootDir/","sources":["inputFile1.ts"],"names":["M","M.constructor"],"mappings":"AAAA,IAAI,CAAC,GAAG,GAAG,CAAC;AACZ,IAAI,GAAG,GAAG,aAAa,CAAC;AACxB,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile1.js +var x = 109; +var foo = "hello world"; +var M = (function () { + function M() { + } + return M; +})(); +//# sourceMappingURL=inputFile1.js.map +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile2.js.map +{"version":3,"file":"inputFile2.js","sourceRoot":"sourceRootDir/","sources":["inputFile2.ts"],"names":["C","C.constructor"],"mappings":"AAAA,IAAI,GAAG,GAAG,wBAAwB,CAAC;AACnC,IAAM,CAAC;IAAPA,SAAMA,CAACA;IAGPC,CAACA;IAADD,QAACA;AAADA,CAACA,AAHD,IAGC"}Filename : tests/cases/fourslash/inputFile2.js +var bar = "hello world Typescript"; +var C = (function () { + function C() { + } + return C; +})(); +//# sourceMappingURL=inputFile2.js.map diff --git a/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline b/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline new file mode 100644 index 00000000000..a5c44fe0d6a --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline @@ -0,0 +1,12 @@ +EmitOutputStatus : EmitErrorEncountered +Filename : tests/cases/fourslash/inputFile.js +var M; +(function (M) { + var C = (function () { + function C() { + } + return C; + })(); + M.foo = new C(); +})(M || (M = {})); + diff --git a/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline b/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline new file mode 100644 index 00000000000..08024a56c9e --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline @@ -0,0 +1,14 @@ +EmitOutputStatus : EmitErrorEncountered +Filename : tests/cases/fourslash/inputFile.js +define(["require", "exports"], function (require, exports) { + var C = (function () { + function C() { + } + return C; + })(); + var M; + (function (M) { + M.foo = new C(); + })(M = exports.M || (exports.M = {})); +}); + diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrors.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrors.baseline new file mode 100644 index 00000000000..dabcd85e854 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrors.baseline @@ -0,0 +1,4 @@ +EmitOutputStatus : JSGeneratedWithSemanticErrors +Filename : tests/cases/fourslash/inputFile.js +var x = "hello world"; + diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline new file mode 100644 index 00000000000..37d0300ac2e --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline @@ -0,0 +1,4 @@ +EmitOutputStatus : DeclaratiionGenerationSkipped +Filename : tests/cases/fourslash/inputFile.js +var x = "hello world"; + diff --git a/tests/baselines/reference/getEmitOutputWithSyntaxErrors.baseline b/tests/baselines/reference/getEmitOutputWithSyntaxErrors.baseline new file mode 100644 index 00000000000..a5d5d2eb9d7 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSyntaxErrors.baseline @@ -0,0 +1,2 @@ +EmitOutputStatus : AllOutputGenerationSkipped + From 94723a9ad1f640985137deda8484b1a4e002e8fc Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 16 Sep 2014 10:28:05 -0700 Subject: [PATCH 29/34] Remove concatenation of syntacticErrors instead return immediately if encountering any error --- src/services/services.ts | 48 +++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index f3e309615ae..15929f18402 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1409,16 +1409,18 @@ module ts { getCanonicalFileName: (filename) => useCaseSensitivefilenames ? filename : filename.toLowerCase(), useCaseSensitiveFileNames: () => useCaseSensitivefilenames, getNewLine: () => "\r\n", - // Need something that doesn't depend on sys.ts here getDefaultLibFilename: (): string => { - return ""; + // In the case there is no host (such as in fourslash test), return "" + return this.host !== undefined ? this.host.getDefaultLibFilename() : ""; }, writeFile: (filename, data, writeByteOrderMark) => { - writer(filename, data, writeByteOrderMark); + if (writer !== undefined) { + writer(filename, data, writeByteOrderMark); + } }, getCurrentDirectory: (): string => { - // Return empty string as in compilerHost using with Visual Studio should not need to getCurrentDirectory since CompilerHost should have absolute path already - return ""; + // In the case there is no host (such as in fourslash test), return "" + return this.host !== undefined ? this.host.getCurrentDirectory() : ""; } }; } @@ -2856,40 +2858,36 @@ module ts { // Initialize writer for CompilerHost.writeFile writer = getEmitOutputWriter; - var syntacticDiagnostics: Diagnostic[] = []; + var syntacticDiagnostics: Diagnostic[] = []; + var containSyntacticErrors = false; + if (emitToSingleFile) { // Check only the file we want to emit - syntacticDiagnostics = program.getDiagnostics(targetSourceFile); - } - else { - // Only check the syntactic of only sourceFiles that will get emitted into single output - forEach(program.getSourceFiles(), sourceFile => { - // Emit to a single file then we will check all files that do not have external module + containSyntacticErrors = containErrors(program.getDiagnostics(targetSourceFile)); + } else { + // Check the syntactic of only sourceFiles that will get emitted into single output + // Terminate the process immediately if we encounter a syntax error from one of the sourceFiles + containSyntacticErrors = program.getSourceFiles().some((sourceFile) => { if (!isExternalModuleOrDeclarationFile(sourceFile)) { - syntacticDiagnostics = syntacticDiagnostics.concat(program.getDiagnostics(sourceFile)); + // If emit to a single file then we will check all files that do not have external module + return containErrors(program.getDiagnostics(sourceFile)); } }); } - // If there is any syntactic error, terminate the process - if (containErrors(syntacticDiagnostics)) { + if (containSyntacticErrors) { + // If there is a syntax error, terminate the process and report outputStatus emitOutput.emitOutputStatus = EmitReturnStatus.AllOutputGenerationSkipped; - // Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput + // Reset writer back to undefined to make sure that we produce an error message + // if CompilerHost.writeFile is called when we are not in getEmitOutput writer = undefined; return emitOutput; } // Perform semantic and force a type check before emit to ensure that all symbols are updated // EmitFiles will report if there is an error from TypeChecker and Emitter - if (emitToSingleFile) { - // Emit only selected file in the project - var emitFilesResult = getFullTypeCheckChecker().emitFiles(targetSourceFile); - } - else { - // Emit all files into single file - var emitFilesResult = getFullTypeCheckChecker().emitFiles(); - } - + // Depend whether we will have to emit into a single file or not either emit only selected file in the project, emit all files into a single file + var emitFilesResult = emitToSingleFile ? getFullTypeCheckChecker().emitFiles(targetSourceFile) : getFullTypeCheckChecker().emitFiles(); emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus; // Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput From 54dcf396744b33a716db40034f4e17f72bb4d852 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 16 Sep 2014 13:19:49 -0700 Subject: [PATCH 30/34] Add getCurrentDirectory and getDefaultLibFilename into interface for host --- src/harness/harnessLanguageService.ts | 8 ++++++++ src/services/services.ts | 2 ++ src/services/shims.ts | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 03c3436f9d5..647d0729cbb 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -207,6 +207,14 @@ module Harness.LanguageService { return this.cancellationToken; } + public getCurrentDirectory(): string { + return ""; + } + + public getDefaultLibFilename(): string { + return ""; + } + public getScriptFileNames(): string { var fileNames: string[] = []; ts.forEachKey(this.fileNameToScript, (fileName) => { fileNames.push(fileName); }); diff --git a/src/services/services.ts b/src/services/services.ts index 15929f18402..a5363eaa802 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -417,6 +417,8 @@ module ts { getScriptSnapshot(fileName: string): TypeScript.IScriptSnapshot; getLocalizedDiagnosticMessages(): any; getCancellationToken(): CancellationToken; + getCurrentDirectory(): string; + getDefaultLibFilename(): string; } // diff --git a/src/services/shims.ts b/src/services/shims.ts index ba7c73d87e3..5145ed96d24 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -53,6 +53,8 @@ module ts { getScriptSnapshot(fileName: string): ScriptSnapshotShim; getLocalizedDiagnosticMessages(): string; getCancellationToken(): CancellationToken; + getCurrentDirectory(): string; + getDefaultLibFilename(): string; } // @@ -365,6 +367,14 @@ module ts { public getCancellationToken(): CancellationToken { return this.shimHost.getCancellationToken(); } + + public getDefaultLibFilename(): string { + return this.shimHost.getDefaultLibFilename(); + } + + public getCurrentDirectory(): string { + return this.shimHost.getCurrentDirectory(); + } } function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any): any { From 58f155d06bd3aefcc6034d45051bee2d7c0487d2 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 16 Sep 2014 15:19:02 -0700 Subject: [PATCH 31/34] Update checking for semanticErrors and fix spelling --- src/compiler/emitter.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f3375a4d9e0..1e6f260f706 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3163,22 +3163,13 @@ module ts { } } - var hasSemanticErros = resolver.hasSemanticErrors(); - var returnCode = EmitReturnStatus.Succeeded; + var hasSemanticErrors = resolver.hasSemanticErrors(); function emitFile(jsFilePath: string, sourceFile?: SourceFile) { emitJavaScript(jsFilePath, sourceFile); - // Update the returnCode with appropriate value depended on whether we have semantic errors - if (!hasSemanticErros && compilerOptions.declaration) { - returnCode = EmitReturnStatus.Succeeded; + if (!hasSemanticErrors && compilerOptions.declaration) { emitDeclarations(jsFilePath, sourceFile); } - else if (hasSemanticErros && compilerOptions.declaration) { - returnCode = EmitReturnStatus.DeclarationGenerationSkipped; - } - else if (hasSemanticErros && !compilerOptions.declaration) { - returnCode = EmitReturnStatus.JSGeneratedWithSemanticErrors; - } } if (targetSourceFile === undefined) { @@ -3206,8 +3197,16 @@ module ts { // Update returnCode if there is any EmitterError var hasEmitterError = forEach(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); + // Check and update returnCode for syntactic and semantic + var returnCode: EmitReturnStatus; if (hasEmitterError) { returnCode = EmitReturnStatus.EmitErrorsEncountered; + } else if (hasSemanticErrors && compilerOptions.declaration) { + returnCode = EmitReturnStatus.DeclarationGenerationSkipped; + } else if (hasSemanticErrors && !compilerOptions.declaration) { + returnCode = EmitReturnStatus.JSGeneratedWithSemanticErrors; + } else { + returnCode = EmitReturnStatus.Succeeded; } return { From e75a1e36942c3f4203c31d862fb279f068942379 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 16 Sep 2014 15:19:41 -0700 Subject: [PATCH 32/34] Change getEmitOutputBaseline --- src/harness/fourslash.ts | 25 ++----------------- src/services/services.ts | 7 +++--- .../getEmitOutputWithEmitterErrors.baseline | 2 +- .../getEmitOutputWithEmitterErrors2.baseline | 2 +- .../getEmitOutputWithSemanticErrors2.baseline | 2 +- 5 files changed, 9 insertions(+), 29 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 30deb174e46..26c10478a46 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -182,7 +182,6 @@ module FourSlash { case testOptMetadataNames.sourceRoot: settings.sourceRoot = globalOptions[prop]; break; - } } } @@ -983,29 +982,9 @@ module FourSlash { emitFiles.forEach(emitFile => { var emitOutput = this.languageService.getEmitOutput(emitFile.fileName); var emitOutputStatus = emitOutput.emitOutputStatus; - // Print emitOutputStatus in readable format - switch (emitOutputStatus) { - case ts.EmitReturnStatus.Succeeded: - resultString += "EmitOutputStatus : Succeeded\n"; - break; - case ts.EmitReturnStatus.AllOutputGenerationSkipped: - resultString += "EmitOutputStatus : AllOutputGenerationSkipped\n"; - break; - case ts.EmitReturnStatus.JSGeneratedWithSemanticErrors: - resultString += "EmitOutputStatus : JSGeneratedWithSemanticErrors\n"; - break; - case ts.EmitReturnStatus.DeclarationGenerationSkipped: - resultString += "EmitOutputStatus : DeclaratiionGenerationSkipped\n"; - break; - case ts.EmitReturnStatus.EmitErrorsEncountered: - resultString += "EmitOutputStatus : EmitErrorEncountered\n"; - break; - default: - resultString += "Invalid EmitOutputStatus\n"; - break; - } - + resultString += "EmitOutputStatus : " + ts.EmitReturnStatus[emitOutputStatus]; + resultString += "\n"; emitOutput.outputFiles.forEach((outputFile, idx, array) => { var filename = "Filename : " + outputFile.name + "\n"; resultString = resultString + filename + outputFile.text; diff --git a/src/services/services.ts b/src/services/services.ts index a5363eaa802..41a4ee2b8ea 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1413,7 +1413,7 @@ module ts { getNewLine: () => "\r\n", getDefaultLibFilename: (): string => { // In the case there is no host (such as in fourslash test), return "" - return this.host !== undefined ? this.host.getDefaultLibFilename() : ""; + return host.getDefaultLibFilename(); }, writeFile: (filename, data, writeByteOrderMark) => { if (writer !== undefined) { @@ -1422,7 +1422,7 @@ module ts { }, getCurrentDirectory: (): string => { // In the case there is no host (such as in fourslash test), return "" - return this.host !== undefined ? this.host.getCurrentDirectory() : ""; + return host.getCurrentDirectory(); } }; } @@ -2869,11 +2869,12 @@ module ts { } else { // Check the syntactic of only sourceFiles that will get emitted into single output // Terminate the process immediately if we encounter a syntax error from one of the sourceFiles - containSyntacticErrors = program.getSourceFiles().some((sourceFile) => { + containSyntacticErrors = forEach(program.getSourceFiles(), sourceFile => { if (!isExternalModuleOrDeclarationFile(sourceFile)) { // If emit to a single file then we will check all files that do not have external module return containErrors(program.getDiagnostics(sourceFile)); } + return false; }); } diff --git a/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline b/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline index a5c44fe0d6a..13df5b18c36 100644 --- a/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline +++ b/tests/baselines/reference/getEmitOutputWithEmitterErrors.baseline @@ -1,4 +1,4 @@ -EmitOutputStatus : EmitErrorEncountered +EmitOutputStatus : EmitErrorsEncountered Filename : tests/cases/fourslash/inputFile.js var M; (function (M) { diff --git a/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline b/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline index 08024a56c9e..c05c01eb91f 100644 --- a/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline +++ b/tests/baselines/reference/getEmitOutputWithEmitterErrors2.baseline @@ -1,4 +1,4 @@ -EmitOutputStatus : EmitErrorEncountered +EmitOutputStatus : EmitErrorsEncountered Filename : tests/cases/fourslash/inputFile.js define(["require", "exports"], function (require, exports) { var C = (function () { diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline index 37d0300ac2e..0dd36c74557 100644 --- a/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrors2.baseline @@ -1,4 +1,4 @@ -EmitOutputStatus : DeclaratiionGenerationSkipped +EmitOutputStatus : DeclarationGenerationSkipped Filename : tests/cases/fourslash/inputFile.js var x = "hello world"; From 0ef50efae15a9eea5a991866b5e762ec136478b0 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 16 Sep 2014 16:04:24 -0700 Subject: [PATCH 33/34] Minor fix on checking getEmitOutputWriter --- src/services/services.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index 41a4ee2b8ea..f78a339460c 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1412,16 +1412,12 @@ module ts { useCaseSensitiveFileNames: () => useCaseSensitivefilenames, getNewLine: () => "\r\n", getDefaultLibFilename: (): string => { - // In the case there is no host (such as in fourslash test), return "" return host.getDefaultLibFilename(); }, writeFile: (filename, data, writeByteOrderMark) => { - if (writer !== undefined) { - writer(filename, data, writeByteOrderMark); - } + writer(filename, data, writeByteOrderMark); }, getCurrentDirectory: (): string => { - // In the case there is no host (such as in fourslash test), return "" return host.getCurrentDirectory(); } }; From bf37eb4c4b89c3ef1a4c199fb75c07128db0415f Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 16 Sep 2014 17:29:45 -0700 Subject: [PATCH 34/34] Fix space formatting --- src/compiler/emitter.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 1e6f260f706..e097d4231a0 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -34,6 +34,7 @@ module ts { } return false; } + export function isExternalModuleOrDeclarationFile(sourceFile: SourceFile) { return isExternalModule(sourceFile) || (sourceFile.flags & NodeFlags.DeclarationFile) !== 0; }