From 0b06ddcc9a3ce02fdd84a00cf9ab4a456028071f Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 12 Sep 2014 12:57:00 -0700 Subject: [PATCH] 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} (90%) 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 90% 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