From f5ed9f3260d58c57e8eb30b2f817c69716aeb3b3 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 27 Feb 2018 10:39:36 -0800 Subject: [PATCH 1/2] Add 'info' diagnostics --- src/compiler/diagnosticMessages.json | 5 + src/compiler/program.ts | 10 +- src/compiler/types.ts | 6 ++ src/harness/fourslash.ts | 28 +++-- src/harness/harness.ts | 4 +- src/harness/harnessLanguageService.ts | 3 + src/harness/unittests/session.ts | 1 + .../unittests/tsserverProjectSystem.ts | 102 +++++++++++++++--- src/harness/virtualFileSystemWithWatch.ts | 5 +- src/server/client.ts | 52 ++++----- src/server/protocol.ts | 20 +++- src/server/session.ts | 94 +++++++++++----- .../convertToEs6Module.ts | 98 ++++------------- src/services/codefixes/fixes.ts | 1 + src/services/infoDiagnostics.ts | 8 ++ src/services/refactors/refactors.ts | 1 - src/services/services.ts | 7 ++ src/services/shims.ts | 8 +- src/services/tsconfig.json | 1 + src/services/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 23 +++- tests/baselines/reference/api/typescript.d.ts | 4 +- tests/cases/fourslash/findAllRefsForModule.ts | 2 - tests/cases/fourslash/fourslash.ts | 5 +- tests/cases/fourslash/javascriptModules22.ts | 2 +- ...refactorConvertToEs6Module_export_alias.ts | 11 +- ...torConvertToEs6Module_export_dotDefault.ts | 12 +-- ...orConvertToEs6Module_export_invalidName.ts | 12 +-- ...vertToEs6Module_export_moduleDotExports.ts | 14 ++- ...le_export_moduleDotExportsEqualsRequire.ts | 12 +-- ..._export_moduleDotExports_changesImports.ts | 11 +- ...refactorConvertToEs6Module_export_named.ts | 20 ++-- ...s6Module_export_namedFunctionExpression.ts | 13 +-- ...efactorConvertToEs6Module_export_object.ts | 12 +-- ...vertToEs6Module_export_object_shorthand.ts | 12 +-- ...torConvertToEs6Module_export_referenced.ts | 12 +-- ...vertToEs6Module_expressionToDeclaration.ts | 12 +-- ...tToEs6Module_import_arrayBindingPattern.ts | 9 +- ...rtToEs6Module_import_includeDefaultUses.ts | 10 +- ...Module_import_multipleUniqueIdentifiers.ts | 14 ++- ...ule_import_multipleVariableDeclarations.ts | 12 +-- ...s6Module_import_nameFromModuleSpecifier.ts | 18 ++-- ...ule_import_objectBindingPattern_complex.ts | 12 +-- ...odule_import_objectBindingPattern_plain.ts | 11 +- ...vertToEs6Module_import_onlyNamedImports.ts | 12 +-- ...onvertToEs6Module_import_propertyAccess.ts | 12 +-- ...ctorConvertToEs6Module_import_shadowing.ts | 14 ++- ...torConvertToEs6Module_import_sideEffect.ts | 9 +- .../refactorConvertToEs6Module_triggers.ts | 13 --- ...ertToEs6Module_triggers_declarationList.ts | 9 -- ...nvertToEs6Module_triggers_noInitializer.ts | 11 -- 51 files changed, 429 insertions(+), 381 deletions(-) rename src/services/{refactors => codefixes}/convertToEs6Module.ts (85%) create mode 100644 src/services/infoDiagnostics.ts delete mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts delete mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_triggers_declarationList.ts delete mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_triggers_noInitializer.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 23549f012a00f..edd9c6534a5ce 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3810,6 +3810,11 @@ "code": 18003 }, + "File is a CommonJS module; it may be converted to an ES6 module.": { + "category": "Info", + "code": 80001 + }, + "Add missing 'super()' call": { "category": "Message", "code": 90001 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 1ce672a6a7536..aba70c7bdfa0a 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -227,8 +227,7 @@ namespace ts { } export function formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): string { - const category = DiagnosticCategory[diagnostic.category].toLowerCase(); - const errorMessage = `${category} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`; + const errorMessage = `${diagnosticCategoryName(diagnostic)} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`; if (diagnostic.file) { const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start); @@ -254,8 +253,9 @@ namespace ts { const ellipsis = "..."; function getCategoryFormat(category: DiagnosticCategory): string { switch (category) { - case DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow; case DiagnosticCategory.Error: return ForegroundColorEscapeSequences.Red; + case DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow; + case DiagnosticCategory.Info: return Debug.fail("Should never get an Info diagnostic on the command line."); case DiagnosticCategory.Message: return ForegroundColorEscapeSequences.Blue; } } @@ -337,9 +337,7 @@ namespace ts { output += " - "; } - const categoryColor = getCategoryFormat(diagnostic.category); - const category = DiagnosticCategory[diagnostic.category].toLowerCase(); - output += formatColorAndReset(category, categoryColor); + output += formatColorAndReset(diagnosticCategoryName(diagnostic), getCategoryFormat(diagnostic.category)); output += formatColorAndReset(` TS${ diagnostic.code }: `, ForegroundColorEscapeSequences.Grey); output += flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6631c66f0eb3c..ca3f059d13b71 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4017,8 +4017,14 @@ namespace ts { export enum DiagnosticCategory { Warning, Error, + Info, Message } + /* @internal */ + export function diagnosticCategoryName(d: { category: DiagnosticCategory }, lowerCase = true): string { + const name = DiagnosticCategory[d.category]; + return lowerCase ? name.toLowerCase() : name; + } export enum ModuleResolutionKind { Classic = 1, diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 88b1c32814e08..0c08f9c63d4de 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -506,8 +506,11 @@ namespace FourSlash { } private getDiagnostics(fileName: string): ts.Diagnostic[] { - return ts.concatenate(this.languageService.getSyntacticDiagnostics(fileName), - this.languageService.getSemanticDiagnostics(fileName)); + return [ + ...this.languageService.getSyntacticDiagnostics(fileName), + ...this.languageService.getSemanticDiagnostics(fileName), + ...this.languageService.getInfoDiagnostics(fileName), + ]; } private getAllDiagnostics(): ts.Diagnostic[] { @@ -578,10 +581,11 @@ namespace FourSlash { return "global"; } - public verifyNoErrors() { + public verifyNoErrors(options: FourSlashInterface.VerifyNoErrorsOptions) { ts.forEachKey(this.inputFiles, fileName => { if (!ts.isAnySupportedFileExtension(fileName)) return; - const errors = this.getDiagnostics(fileName); + let errors = this.getDiagnostics(fileName); + if (options.ignoreInfoDiagnostics) errors = errors.filter(e => e.category !== ts.DiagnosticCategory.Info); if (errors.length) { this.printErrorLog(/*expectErrors*/ false, errors); const error = errors[0]; @@ -1246,6 +1250,10 @@ Actual: ${stringify(fullActual)}`); this.testDiagnostics(expected, diagnostics); } + public getInfoDiagnostics(expected: ReadonlyArray): void { + this.testDiagnostics(expected, this.languageService.getInfoDiagnostics(this.activeFile.fileName)); + } + private testDiagnostics(expected: ReadonlyArray, diagnostics: ReadonlyArray) { assert.deepEqual(ts.realizeDiagnostics(diagnostics, ts.newLineCharacter), expected); } @@ -4138,8 +4146,8 @@ namespace FourSlashInterface { this.state.verifyCurrentSignatureHelpIs(expected); } - public noErrors() { - this.state.verifyNoErrors(); + public noErrors(options: VerifyNoErrorsOptions = {}) { + this.state.verifyNoErrors(options); } public numberOfErrorsInCurrentFile(expected: number) { @@ -4327,6 +4335,10 @@ namespace FourSlashInterface { this.state.getSemanticDiagnostics(expected); } + public getInfoDiagnostics(expected: ReadonlyArray) { + this.state.getInfoDiagnostics(expected); + } + public ProjectInfo(expected: string[]) { this.state.verifyProjectInfo(expected); } @@ -4665,4 +4677,8 @@ namespace FourSlashInterface { source?: string; description: string; } + + export interface VerifyNoErrorsOptions { + ignoreInfoDiagnostics?: boolean; + } } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d3bd537ad4c08..e2bed4f0318ed 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -242,7 +242,7 @@ namespace Utils { start: diagnostic.start, length: diagnostic.length, messageText: ts.flattenDiagnosticMessageText(diagnostic.messageText, Harness.IO.newLine()), - category: (ts).DiagnosticCategory[diagnostic.category], + category: ts.diagnosticCategoryName(diagnostic, /*lowerCase*/ false), code: diagnostic.code }; } @@ -1376,7 +1376,7 @@ namespace Harness { .split("\n") .map(s => s.length > 0 && s.charAt(s.length - 1) === "\r" ? s.substr(0, s.length - 1) : s) .filter(s => s.length > 0) - .map(s => "!!! " + ts.DiagnosticCategory[error.category].toLowerCase() + " TS" + error.code + ": " + s); + .map(s => "!!! " + ts.diagnosticCategoryName(error) + " TS" + error.code + ": " + s); errLines.forEach(e => outputLines += (newLine() + e)); errorsReported++; diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index c38ab1f3c6df3..4263f3fc1d89f 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -402,6 +402,9 @@ namespace Harness.LanguageService { getSemanticDiagnostics(fileName: string): ts.Diagnostic[] { return unwrapJSONCallResult(this.shim.getSemanticDiagnostics(fileName)); } + getInfoDiagnostics(fileName: string): ts.Diagnostic[] { + return unwrapJSONCallResult(this.shim.getInfoDiagnostics(fileName)); + } getCompilerOptionsDiagnostics(): ts.Diagnostic[] { return unwrapJSONCallResult(this.shim.getCompilerOptionsDiagnostics()); } diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 765fc29ee49b7..50961840de216 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -216,6 +216,7 @@ namespace ts.server { CommandNames.GeterrForProject, CommandNames.SemanticDiagnosticsSync, CommandNames.SyntacticDiagnosticsSync, + CommandNames.InfoDiagnosticsSync, CommandNames.NavBar, CommandNames.NavBarFull, CommandNames.Navto, diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index e09dff2a6d5dd..a8b13f6035940 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -467,12 +467,12 @@ namespace ts.projectSystem { verifyDiagnostics(actual, []); } - function checkErrorMessage(session: TestSession, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) { - checkNthEvent(session, ts.server.toEvent(eventName, diagnostics), 0, /*isMostRecent*/ false); + function checkErrorMessage(session: TestSession, eventName: protocol.DiagnosticEventKind, diagnostics: protocol.DiagnosticEventBody, isMostRecent = false): void { + checkNthEvent(session, ts.server.toEvent(eventName, diagnostics), 0, isMostRecent); } - function checkCompleteEvent(session: TestSession, numberOfCurrentEvents: number, expectedSequenceId: number) { - checkNthEvent(session, ts.server.toEvent("requestCompleted", { request_seq: expectedSequenceId }), numberOfCurrentEvents - 1, /*isMostRecent*/ true); + function checkCompleteEvent(session: TestSession, numberOfCurrentEvents: number, expectedSequenceId: number, isMostRecent = true): void { + checkNthEvent(session, ts.server.toEvent("requestCompleted", { request_seq: expectedSequenceId }), numberOfCurrentEvents - 1, isMostRecent); } function checkProjectUpdatedInBackgroundEvent(session: TestSession, openFiles: string[]) { @@ -3076,8 +3076,13 @@ namespace ts.projectSystem { host.runQueuedImmediateCallbacks(); assert.isFalse(hasError()); checkErrorMessage(session, "semanticDiag", { file: untitledFile, diagnostics: [] }); + session.clearMessages(); + host.runQueuedImmediateCallbacks(1); + assert.isFalse(hasError()); + checkErrorMessage(session, "infoDiag", { file: untitledFile, diagnostics: [] }); checkCompleteEvent(session, 2, expectedSequenceId); + session.clearMessages(); } it("has projectRoot", () => { @@ -3136,6 +3141,10 @@ namespace ts.projectSystem { host.runQueuedImmediateCallbacks(); checkErrorMessage(session, "semanticDiag", { file: app.path, diagnostics: [] }); + session.clearMessages(); + + host.runQueuedImmediateCallbacks(1); + checkErrorMessage(session, "infoDiag", { file: app.path, diagnostics: [] }); checkCompleteEvent(session, 2, expectedSequenceId); session.clearMessages(); } @@ -3934,18 +3943,17 @@ namespace ts.projectSystem { session.clearMessages(); host.runQueuedImmediateCallbacks(); - const moduleNotFound = Diagnostics.Cannot_find_module_0; const startOffset = file1.content.indexOf('"') + 1; checkErrorMessage(session, "semanticDiag", { - file: file1.path, diagnostics: [{ - start: { line: 1, offset: startOffset }, - end: { line: 1, offset: startOffset + '"pad"'.length }, - text: formatStringFromArgs(moduleNotFound.message, ["pad"]), - code: moduleNotFound.code, - category: DiagnosticCategory[moduleNotFound.category].toLowerCase(), - source: undefined - }] + file: file1.path, + diagnostics: [ + createDiagnostic({ line: 1, offset: startOffset }, { line: 1, offset: startOffset + '"pad"'.length }, Diagnostics.Cannot_find_module_0, ["pad"]) + ], }); + session.clearMessages(); + + host.runQueuedImmediateCallbacks(1); + checkErrorMessage(session, "infoDiag", { file: file1.path, diagnostics: [] }); checkCompleteEvent(session, 2, expectedSequenceId); session.clearMessages(); @@ -3966,6 +3974,63 @@ namespace ts.projectSystem { host.runQueuedImmediateCallbacks(); checkErrorMessage(session, "semanticDiag", { file: file1.path, diagnostics: [] }); }); + + it("info diagnostics", () => { + const file: FileOrFolder = { + path: "/a.js", + content: 'require("b")', + }; + + const host = createServerHost([file]); + const session = createSession(host, { canUseEvents: true }); + const service = session.getProjectService(); + + session.executeCommandSeq({ + command: server.CommandNames.Open, + arguments: { file: file.path, fileContent: file.content }, + }); + + checkNumberOfProjects(service, { inferredProjects: 1 }); + session.clearMessages(); + const expectedSequenceId = session.getNextSeq(); + host.checkTimeoutQueueLengthAndRun(2); + + checkProjectUpdatedInBackgroundEvent(session, [file.path]); + session.clearMessages(); + + session.executeCommandSeq({ + command: server.CommandNames.Geterr, + arguments: { + delay: 0, + files: [file.path], + } + }); + + host.checkTimeoutQueueLengthAndRun(1); + + checkErrorMessage(session, "syntaxDiag", { file: file.path, diagnostics: [] }, /*isMostRecent*/ true); + session.clearMessages(); + + host.runQueuedImmediateCallbacks(1); + + checkErrorMessage(session, "semanticDiag", { file: file.path, diagnostics: [] }); + session.clearMessages(); + + host.runQueuedImmediateCallbacks(1); + + checkErrorMessage(session, "infoDiag", { + file: file.path, + diagnostics: [ + createDiagnostic({ line: 1, offset: 1 }, { line: 1, offset: 13 }, Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module) + ], + }); + checkCompleteEvent(session, 2, expectedSequenceId); + session.clearMessages(); + }); + + function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: ReadonlyArray = []): protocol.Diagnostic { + return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category: diagnosticCategoryName(message), source: undefined }; + } }); describe("tsserverProjectSystem Configure file diagnostics events", () => { @@ -5154,9 +5219,15 @@ namespace ts.projectSystem { // the semanticDiag message host.runQueuedImmediateCallbacks(); - assert.equal(host.getOutput().length, 2, "expect 2 messages"); + assert.equal(host.getOutput().length, 1); const e2 = getMessage(0); assert.equal(e2.event, "semanticDiag"); + session.clearMessages(); + + host.runQueuedImmediateCallbacks(1); + assert.equal(host.getOutput().length, 2); + const e3 = getMessage(0); + assert.equal(e3.event, "infoDiag"); verifyRequestCompleted(getErrId, 1); cancellationToken.resetToken(); @@ -5194,6 +5265,7 @@ namespace ts.projectSystem { return JSON.parse(server.extractMessage(host.getOutput()[n])); } }); + it("Lower priority tasks are cancellable", () => { const f1 = { path: "/a/app.ts", @@ -5495,7 +5567,7 @@ namespace ts.projectSystem { } type CalledMaps = CalledMapsWithSingleArg | CalledMapsWithFiveArgs; function createCallsTrackingHost(host: TestServerHost) { - const calledMaps: Record> & Record, ReadonlyArray, ReadonlyArray, number]>> = { + const calledMaps: Record> & Record, ReadonlyArray, ReadonlyArray, number]>> = { fileExists: setCallsTrackingWithSingleArgFn(CalledMapsWithSingleArg.fileExists), directoryExists: setCallsTrackingWithSingleArgFn(CalledMapsWithSingleArg.directoryExists), getDirectories: setCallsTrackingWithSingleArgFn(CalledMapsWithSingleArg.getDirectories), diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 93fdc6cdbc623..54a353a59c6da 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -708,7 +708,10 @@ interface Array {}` } } - runQueuedImmediateCallbacks() { + runQueuedImmediateCallbacks(checkCount?: number) { + if (checkCount !== undefined) { + assert.equal(this.immediateCallbacks.count(), checkCount); + } this.immediateCallbacks.invoke(); } diff --git a/src/server/client.ts b/src/server/client.ts index cee65c0e5a485..2b41426911c92 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -75,7 +75,7 @@ namespace ts.server { return { span: this.decodeSpan(codeEdit, fileName), newText: codeEdit.newText }; } - private processRequest(command: string, args?: any): T { + private processRequest(command: string, args?: T["arguments"]): T { const request: protocol.Request = { seq: this.sequence, type: "request", @@ -343,41 +343,31 @@ namespace ts.server { } getSyntacticDiagnostics(file: string): Diagnostic[] { - const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true }; - - const request = this.processRequest(CommandNames.SyntacticDiagnosticsSync, args); - const response = this.processResponse(request); - - return (response.body).map(entry => this.convertDiagnostic(entry, file)); + return this.getDiagnostics(file, CommandNames.SyntacticDiagnosticsSync); } - getSemanticDiagnostics(file: string): Diagnostic[] { - const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true }; - - const request = this.processRequest(CommandNames.SemanticDiagnosticsSync, args); - const response = this.processResponse(request); - - return (response.body).map(entry => this.convertDiagnostic(entry, file)); + return this.getDiagnostics(file, CommandNames.SemanticDiagnosticsSync); + } + getInfoDiagnostics(file: string): Diagnostic[] { + return this.getDiagnostics(file, CommandNames.InfoDiagnosticsSync); } - convertDiagnostic(entry: protocol.DiagnosticWithLinePosition, _fileName: string): Diagnostic { - let category: DiagnosticCategory; - for (const id in DiagnosticCategory) { - if (isString(id) && entry.category === id.toLowerCase()) { - category = (DiagnosticCategory)[id]; - } - } - - Debug.assert(category !== undefined, "convertDiagnostic: category should not be undefined"); + private getDiagnostics(file: string, command: CommandNames) { + const request = this.processRequest(command, { file, includeLinePosition: true }); + const response = this.processResponse(request); - return { - file: undefined, - start: entry.start, - length: entry.length, - messageText: entry.message, - category, - code: entry.code - }; + return (response.body).map(entry => { + const category = firstDefined(Object.keys(DiagnosticCategory), id => + isString(id) && entry.category === id.toLowerCase() ? (DiagnosticCategory)[id] : undefined); + return { + file: undefined, + start: entry.start, + length: entry.length, + messageText: entry.message, + category: Debug.assertDefined(category, "convertDiagnostic: category should not be undefined"), + code: entry.code + }; + }); } getCompilerOptionsDiagnostics(): Diagnostic[] { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 76d954ebe23fa..f763f78bb94ff 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -42,6 +42,7 @@ namespace ts.server.protocol { GeterrForProject = "geterrForProject", SemanticDiagnosticsSync = "semanticDiagnosticsSync", SyntacticDiagnosticsSync = "syntacticDiagnosticsSync", + InfoDiagnosticsSync = "infoDiagnosticsSync", NavBar = "navbar", /* @internal */ NavBarFull = "navbar-full", @@ -2010,6 +2011,19 @@ namespace ts.server.protocol { body?: Diagnostic[] | DiagnosticWithLinePosition[]; } + export interface InfoDiagnosticsSyncRequest extends FileRequest { + command: CommandTypes.InfoDiagnosticsSync; + arguments: InfoDiagnosticsSyncRequestArgs; + } + + export interface InfoDiagnosticsSyncRequestArgs extends FileRequestArgs { + includeLinePosition?: boolean; + } + + export interface InfoDiagnosticsSyncResponse extends Response { + body?: Diagnostic[] | DiagnosticWithLinePosition[]; + } + /** * Synchronous request for syntactic diagnostics of one file. */ @@ -2121,7 +2135,7 @@ namespace ts.server.protocol { text: string; /** - * The category of the diagnostic message, e.g. "error" vs. "warning" + * The category of the diagnostic message. This is the lower-case of a DiagnosticCategory member. */ category: string; @@ -2155,8 +2169,10 @@ namespace ts.server.protocol { diagnostics: Diagnostic[]; } + export type DiagnosticEventKind = "semanticDiag" | "syntaxDiag" | "infoDiag"; + /** - * Event message for "syntaxDiag" and "semanticDiag" event types. + * Event message for DiagnosticEventKind event types. * These events provide syntactic and semantic errors for a file. */ export interface DiagnosticEvent extends Event { diff --git a/src/server/session.ts b/src/server/session.ts index bff19d7bc232f..15fb40e3b0c9d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -79,7 +79,7 @@ namespace ts.server { end: scriptInfo.positionToLineOffset(diag.start + diag.length), text: flattenDiagnosticMessageText(diag.messageText, "\n"), code: diag.code, - category: DiagnosticCategory[diag.category].toLowerCase(), + category: diagnosticCategoryName(diag), source: diag.source }; } @@ -95,7 +95,7 @@ namespace ts.server { const end = diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start + diag.length)); const text = flattenDiagnosticMessageText(diag.messageText, "\n"); const { code, source } = diag; - const category = DiagnosticCategory[diag.category].toLowerCase(); + const category = diagnosticCategoryName(diag); return includeFileName ? { start, end, text, code, category, source, fileName: diag.file && diag.file.fileName } : { start, end, text, code, category, source }; } @@ -467,13 +467,10 @@ namespace ts.server { private semanticCheck(file: NormalizedPath, project: Project) { try { - let diags: ReadonlyArray = emptyArray; - if (!isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) { - diags = project.getLanguageService().getSemanticDiagnostics(file); - } - - const bakedDiags = diags.map((diag) => formatDiag(file, project, diag)); - this.event({ file, diagnostics: bakedDiags }, "semanticDiag"); + const diags = isDeclarationFileInJSOnlyNonConfiguredProject(project, file) + ? emptyArray + : project.getLanguageService().getSemanticDiagnostics(file); + this.sendDiagnosticsEvent(file, project, diags, "semanticDiag"); } catch (err) { this.logError(err, "semantic check"); @@ -482,10 +479,10 @@ namespace ts.server { private syntacticCheck(file: NormalizedPath, project: Project) { try { - const diags = project.getLanguageService().getSyntacticDiagnostics(file); - if (diags) { - const bakedDiags = diags.map((diag) => formatDiag(file, project, diag)); - this.event({ file, diagnostics: bakedDiags }, "syntaxDiag"); + // TODO: why do we check for diagnostics existence here, but in semanticCheck send unconditionally? + const diagnostics = project.getLanguageService().getSyntacticDiagnostics(file); + if (diagnostics) { + this.sendDiagnosticsEvent(file, project, diagnostics, "syntaxDiag"); } } catch (err) { @@ -493,27 +490,53 @@ namespace ts.server { } } + private infoCheck(file: NormalizedPath, project: Project) { + try { + this.sendDiagnosticsEvent(file, project, project.getLanguageService().getInfoDiagnostics(file), "infoDiag"); + } + catch (err) { + this.logError(err, "info check"); + } + } + + private sendDiagnosticsEvent(file: NormalizedPath, project: Project, diagnostics: ReadonlyArray, kind: protocol.DiagnosticEventKind): void { + this.event({ file, diagnostics: diagnostics.map(diag => formatDiag(file, project, diag)) }, kind); + } + private updateErrorCheck(next: NextStep, checkList: PendingErrorCheck[], ms: number, requireOpen = true) { const seq = this.changeSeq; const followMs = Math.min(ms, 200); let index = 0; const checkOne = () => { - if (this.changeSeq === seq) { - const checkSpec = checkList[index]; - index++; - if (checkSpec.project.containsFile(checkSpec.fileName, requireOpen)) { - this.syntacticCheck(checkSpec.fileName, checkSpec.project); - if (this.changeSeq === seq) { - next.immediate(() => { - this.semanticCheck(checkSpec.fileName, checkSpec.project); - if (checkList.length > index) { - next.delay(followMs, checkOne); - } - }); - } - } + if (this.changeSeq !== seq) { + return; + } + + const { fileName, project } = checkList[index]; + index++; + if (!project.containsFile(fileName, requireOpen)) { + return; } + + this.syntacticCheck(fileName, project); + if (this.changeSeq !== seq) { + return; + } + + next.immediate(() => { + this.semanticCheck(fileName, project); + if (this.changeSeq !== seq) { + return; + } + + next.immediate(() => { + this.infoCheck(fileName, project); + if (checkList.length > index) { + next.delay(followMs, checkOne); + } + }); + }); }; if (checkList.length > index && this.changeSeq === seq) { @@ -580,7 +603,7 @@ namespace ts.server { message: flattenDiagnosticMessageText(d.messageText, this.host.newLine), start: d.start, length: d.length, - category: DiagnosticCategory[d.category].toLowerCase(), + category: diagnosticCategoryName(d), code: d.code, startLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start)), endLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start + d.length)) @@ -606,7 +629,7 @@ namespace ts.server { message: flattenDiagnosticMessageText(d.messageText, this.host.newLine), start: d.start, length: d.length, - category: DiagnosticCategory[d.category].toLowerCase(), + category: diagnosticCategoryName(d), code: d.code, source: d.source, startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start), @@ -756,6 +779,16 @@ namespace ts.server { return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition); } + private getInfoDiagnosticsSync(args: protocol.InfoDiagnosticsSyncRequestArgs): ReadonlyArray | ReadonlyArray { + const { configFile } = this.getConfigFileAndProject(args); + if (configFile) { + // Currently there are no info diagnostics for config files. + return emptyArray; + } + // isSemantic because we don't want to info diagnostics in declaration files for JS-only users + return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getInfoDiagnostics(file), args.includeLinePosition); + } + private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); @@ -1953,6 +1986,9 @@ namespace ts.server { [CommandNames.SyntacticDiagnosticsSync]: (request: protocol.SyntacticDiagnosticsSyncRequest) => { return this.requiredResponse(this.getSyntacticDiagnosticsSync(request.arguments)); }, + [CommandNames.InfoDiagnosticsSync]: (request: protocol.InfoDiagnosticsSyncRequest) => { + return this.requiredResponse(this.getInfoDiagnosticsSync(request.arguments)); + }, [CommandNames.Geterr]: (request: protocol.GeterrRequest) => { this.errorCheck.startNew(next => this.getDiagnostics(next, request.arguments.delay, request.arguments.files)); return this.notRequired(); diff --git a/src/services/refactors/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts similarity index 85% rename from src/services/refactors/convertToEs6Module.ts rename to src/services/codefixes/convertToEs6Module.ts index 6ed9cbec2ee97..dfd8ff10b420a 100644 --- a/src/services/refactors/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -1,85 +1,23 @@ /* @internal */ -namespace ts.refactor { - const actionName = "Convert to ES6 module"; - const description = getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module); - registerRefactor(actionName, { getEditsForAction, getAvailableActions }); - - function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { - const { file, startPosition } = context; - if (!isSourceFileJavaScript(file) || !file.commonJsModuleIndicator) { - return undefined; - } - - const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); - return !isAtTriggerLocation(file, node) ? undefined : [ - { - name: actionName, - description, - actions: [ - { - description, - name: actionName, - }, - ], - }, - ]; - } - - function isAtTriggerLocation(sourceFile: SourceFile, node: Node, onSecondTry = false): boolean { - switch (node.kind) { - case SyntaxKind.CallExpression: - return isAtTopLevelRequire(node as CallExpression); - case SyntaxKind.PropertyAccessExpression: - return isExportsOrModuleExportsOrAlias(sourceFile, node as PropertyAccessExpression) - || isExportsOrModuleExportsOrAlias(sourceFile, (node as PropertyAccessExpression).expression); - case SyntaxKind.VariableDeclarationList: - return isVariableDeclarationTriggerLocation(firstOrUndefined((node as VariableDeclarationList).declarations)); - case SyntaxKind.VariableDeclaration: - return isVariableDeclarationTriggerLocation(node as VariableDeclaration); - default: - return isExpression(node) && isExportsOrModuleExportsOrAlias(sourceFile, node) - || !onSecondTry && isAtTriggerLocation(sourceFile, node.parent, /*onSecondTry*/ true); - } - - function isVariableDeclarationTriggerLocation(decl: VariableDeclaration | undefined) { - return !!decl && !!decl.initializer && isExportsOrModuleExportsOrAlias(sourceFile, decl.initializer); - } - } - - function isAtTopLevelRequire(call: CallExpression): boolean { - if (!isRequireCall(call, /*checkArgumentIsStringLiteral*/ true)) { - return false; - } - const { parent: propAccess } = call; - const varDecl = isPropertyAccessExpression(propAccess) ? propAccess.parent : propAccess; - if (isExpressionStatement(varDecl) && isSourceFile(varDecl.parent)) { // `require("x");` as a statement - return true; - } - if (!isVariableDeclaration(varDecl)) { - return false; - } - const { parent: varDeclList } = varDecl; - if (varDeclList.kind !== SyntaxKind.VariableDeclarationList) { - return false; - } - const { parent: varStatement } = varDeclList; - return varStatement.kind === SyntaxKind.VariableStatement && varStatement.parent.kind === SyntaxKind.SourceFile; - } - - function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined { - Debug.assertEqual(actionName, _actionName); - const { file, program } = context; - Debug.assert(isSourceFileJavaScript(file)); - const edits = textChanges.ChangeTracker.with(context, changes => { - const moduleExportsChangedToDefault = convertFileToEs6Module(file, program.getTypeChecker(), changes, program.getCompilerOptions().target); - if (moduleExportsChangedToDefault) { - for (const importingFile of program.getSourceFiles()) { - fixImportOfModuleExports(importingFile, file, changes); +namespace ts.codefix { + const errorCodes = [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module.code]; + registerCodeFix({ + errorCodes, + getCodeActions(context) { + const description = getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module); + const { sourceFile, program } = context; + const changes = textChanges.ChangeTracker.with(context, changes => { + const moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, program.getCompilerOptions().target); + if (moduleExportsChangedToDefault) { + for (const importingFile of program.getSourceFiles()) { + fixImportOfModuleExports(importingFile, sourceFile, changes); + } } - } - }); - return { edits, renameFilename: undefined, renameLocation: undefined }; - } + }); + // No support for fix-all since this applies to the whole file at once anyway. + return [{ description, changes, fixId: undefined }]; + }, + }); function fixImportOfModuleExports(importingFile: ts.SourceFile, exportingFile: ts.SourceFile, changes: textChanges.ChangeTracker) { for (const moduleSpecifier of importingFile.imports) { diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index 671f2251a328c..24b726717a04d 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -1,4 +1,5 @@ /// +/// /// /// /// diff --git a/src/services/infoDiagnostics.ts b/src/services/infoDiagnostics.ts new file mode 100644 index 0000000000000..8d0493d34af7a --- /dev/null +++ b/src/services/infoDiagnostics.ts @@ -0,0 +1,8 @@ +/* @internal */ +namespace ts { + export function infoDiagnostics(sourceFile: SourceFile): Diagnostic[] { + return sourceFile.commonJsModuleIndicator + ? [createDiagnosticForNode(sourceFile.commonJsModuleIndicator, Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module)] + : emptyArray; + } +} diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index 8b4561700d554..3858b1987434e 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -1,6 +1,5 @@ /// /// -/// /// /// /// diff --git a/src/services/services.ts b/src/services/services.ts index a4da9b12eadd7..31633fcb184f7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -10,6 +10,7 @@ /// /// /// +/// /// /// /// @@ -1419,6 +1420,11 @@ namespace ts { return [...semanticDiagnostics, ...declarationDiagnostics]; } + function getInfoDiagnostics(fileName: string): Diagnostic[] { + synchronizeHostData(); + return infoDiagnostics(getValidSourceFile(fileName)); + } + function getCompilerOptionsDiagnostics() { synchronizeHostData(); return [...program.getOptionsDiagnostics(cancellationToken), ...program.getGlobalDiagnostics(cancellationToken)]; @@ -2101,6 +2107,7 @@ namespace ts { cleanupSemanticCache, getSyntacticDiagnostics, getSemanticDiagnostics, + getInfoDiagnostics, getCompilerOptionsDiagnostics, getSyntacticClassifications, getSemanticClassifications, diff --git a/src/services/shims.ts b/src/services/shims.ts index 5abf5da2c0719..66e74ee97e6a6 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -144,6 +144,7 @@ namespace ts { getSyntacticDiagnostics(fileName: string): string; getSemanticDiagnostics(fileName: string): string; + getInfoDiagnostics(fileName: string): string; getCompilerOptionsDiagnostics(): string; getSyntacticClassifications(fileName: string, start: number, length: number): string; @@ -597,8 +598,7 @@ namespace ts { message: flattenDiagnosticMessageText(diagnostic.messageText, newLine), start: diagnostic.start, length: diagnostic.length, - /// TODO: no need for the tolowerCase call - category: DiagnosticCategory[diagnostic.category].toLowerCase(), + category: diagnosticCategoryName(diagnostic), code: diagnostic.code }; } @@ -716,6 +716,10 @@ namespace ts { }); } + public getInfoDiagnostics(fileName: string): string { + return this.forwardJSONCall(`getInfoDiagnostics('${fileName}')`, () => this.realizeDiagnostics(this.languageService.getInfoDiagnostics(fileName))); + } + public getCompilerOptionsDiagnostics(): string { return this.forwardJSONCall( "getCompilerOptionsDiagnostics()", diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index bbd88a1a00401..a3e5deb59f2d1 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -53,6 +53,7 @@ "documentRegistry.ts", "findAllReferences.ts", "importTracker.ts", + "infoDiagnostics.ts", "goToDefinition.ts", "jsDoc.ts", "jsTyping.ts", diff --git a/src/services/types.ts b/src/services/types.ts index b67c2569f27f8..7b5ecd1ca69d9 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -223,6 +223,7 @@ namespace ts { getSyntacticDiagnostics(fileName: string): Diagnostic[]; getSemanticDiagnostics(fileName: string): Diagnostic[]; + getInfoDiagnostics(fileName: string): Diagnostic[]; // TODO: Rename this to getProgramDiagnostics to better indicate that these are any // diagnostics present for the program level, and not just 'options' diagnostics. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 9f5ceb1f0cb5e..719771b831df4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2262,7 +2262,8 @@ declare namespace ts { enum DiagnosticCategory { Warning = 0, Error = 1, - Message = 2, + Info = 2, + Message = 3, } enum ModuleResolutionKind { Classic = 1, @@ -4054,6 +4055,7 @@ declare namespace ts { cleanupSemanticCache(): void; getSyntacticDiagnostics(fileName: string): Diagnostic[]; getSemanticDiagnostics(fileName: string): Diagnostic[]; + getInfoDiagnostics(fileName: string): Diagnostic[]; getCompilerOptionsDiagnostics(): Diagnostic[]; /** * @deprecated Use getEncodedSyntacticClassifications instead. @@ -5024,6 +5026,7 @@ declare namespace ts.server.protocol { GeterrForProject = "geterrForProject", SemanticDiagnosticsSync = "semanticDiagnosticsSync", SyntacticDiagnosticsSync = "syntacticDiagnosticsSync", + InfoDiagnosticsSync = "infoDiagnosticsSync", NavBar = "navbar", Navto = "navto", NavTree = "navtree", @@ -6546,6 +6549,16 @@ declare namespace ts.server.protocol { interface SemanticDiagnosticsSyncResponse extends Response { body?: Diagnostic[] | DiagnosticWithLinePosition[]; } + interface InfoDiagnosticsSyncRequest extends FileRequest { + command: CommandTypes.InfoDiagnosticsSync; + arguments: InfoDiagnosticsSyncRequestArgs; + } + interface InfoDiagnosticsSyncRequestArgs extends FileRequestArgs { + includeLinePosition?: boolean; + } + interface InfoDiagnosticsSyncResponse extends Response { + body?: Diagnostic[] | DiagnosticWithLinePosition[]; + } /** * Synchronous request for syntactic diagnostics of one file. */ @@ -6642,7 +6655,7 @@ declare namespace ts.server.protocol { */ text: string; /** - * The category of the diagnostic message, e.g. "error" vs. "warning" + * The category of the diagnostic message. This is the lower-case of a DiagnosticCategory member. */ category: string; /** @@ -6670,8 +6683,9 @@ declare namespace ts.server.protocol { */ diagnostics: Diagnostic[]; } + type DiagnosticEventKind = "semanticDiag" | "syntaxDiag" | "infoDiag"; /** - * Event message for "syntaxDiag" and "semanticDiag" event types. + * Event message for DiagnosticEventKind event types. * These events provide syntactic and semantic errors for a file. */ interface DiagnosticEvent extends Event { @@ -7206,6 +7220,8 @@ declare namespace ts.server { private doOutput(info, cmdName, reqSeq, success, message?); private semanticCheck(file, project); private syntacticCheck(file, project); + private infoCheck(file, project); + private sendDiagnosticsEvent(file, project, diagnostics, kind); private updateErrorCheck(next, checkList, ms, requireOpen?); private cleanProjects(caption, projects); private cleanup(); @@ -7226,6 +7242,7 @@ declare namespace ts.server { private getOccurrences(args); private getSyntacticDiagnosticsSync(args); private getSemanticDiagnosticsSync(args); + private getInfoDiagnosticsSync(args); private getDocumentHighlights(args, simplifiedResult); private setCompilerOptionsForInferredProjects(args); private getProjectInfo(args); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index e5fb0b1e1692c..8e48c67c24e72 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2262,7 +2262,8 @@ declare namespace ts { enum DiagnosticCategory { Warning = 0, Error = 1, - Message = 2, + Info = 2, + Message = 3, } enum ModuleResolutionKind { Classic = 1, @@ -4306,6 +4307,7 @@ declare namespace ts { cleanupSemanticCache(): void; getSyntacticDiagnostics(fileName: string): Diagnostic[]; getSemanticDiagnostics(fileName: string): Diagnostic[]; + getInfoDiagnostics(fileName: string): Diagnostic[]; getCompilerOptionsDiagnostics(): Diagnostic[]; /** * @deprecated Use getEncodedSyntacticClassifications instead. diff --git a/tests/cases/fourslash/findAllRefsForModule.ts b/tests/cases/fourslash/findAllRefsForModule.ts index bff3aa1778560..a8641625075ef 100644 --- a/tests/cases/fourslash/findAllRefsForModule.ts +++ b/tests/cases/fourslash/findAllRefsForModule.ts @@ -14,8 +14,6 @@ // @Filename: /d.ts //// /// -verify.noErrors(); - const ranges = test.ranges(); const [r0, r1, r2] = ranges; verify.referenceGroups(ranges, [{ definition: 'module "/a"', ranges: [r0, r2, r1] }]); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 9680eb822a73f..47f78782df194 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -282,7 +282,9 @@ declare namespace FourSlashInterface { currentSignatureTypeParameterCountIs(expected: number): void; currentSignatureHelpIs(expected: string): void; // Checks that there are no compile errors. - noErrors(): void; + noErrors(options?: { + ignoreInfoDiagnostics?: boolean, + }): void; numberOfErrorsInCurrentFile(expected: number): void; baselineCurrentFileBreakpointLocations(): void; baselineCurrentFileNameOrDottedNameSpans(): void; @@ -349,6 +351,7 @@ declare namespace FourSlashInterface { }, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[]): void; getSyntacticDiagnostics(expected: ReadonlyArray): void; getSemanticDiagnostics(expected: ReadonlyArray): void; + getInfoDiagnostics(expected: ReadonlyArray): void; ProjectInfo(expected: string[]): void; allRangesAppearInImplementationList(markerName: string): void; } diff --git a/tests/cases/fourslash/javascriptModules22.ts b/tests/cases/fourslash/javascriptModules22.ts index caa8c6798b19d..5e68f86abbc13 100644 --- a/tests/cases/fourslash/javascriptModules22.ts +++ b/tests/cases/fourslash/javascriptModules22.ts @@ -29,4 +29,4 @@ verify.completionListContains("name"); edit.insert("name;\nsausages."); verify.completionListContains("eggs"); edit.insert("eggs;"); -verify.noErrors(); +verify.noErrors({ ignoreInfoDiagnostics: true }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts index 6529bb64af045..73cd606adf949 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts @@ -5,14 +5,11 @@ // @Filename: /a.js ////const exportsAlias = exports; ////exportsAlias.f = function() {}; -/////*a*/module/*b*/.exports = exportsAlias; +////module.exports = exportsAlias; -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: ` +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: ` export function f() { } `, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts index 1c8633eb4eb2b..1283b0053a8ca 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts @@ -5,15 +5,13 @@ // @allowJs: true // @Filename: /a.js -/////*a*/exports/*b*/.default = 0; +////exports.default = 0; ////exports.default; -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `const _default = 0; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`const _default = 0; export { _default as default }; _default;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts index 16b48fcd20467..83a831effb0d5 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts @@ -5,15 +5,13 @@ // @allowJs: true // @Filename: /a.js -/////*a*/exports/*b*/.class = 0; +////exports.class = 0; ////exports.async = 1; -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `const _class = 0; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`const _class = 0; export { _class as class }; export const async = 1;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts index ddcf79d0114db..3382228babbf7 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: /a.js -/////*a*/module/*b*/.exports = function() {} +////module.exports = function() {} ////module.exports = function f() {} ////module.exports = class {} ////module.exports = class C {} @@ -11,16 +11,14 @@ // See also `refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts` -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `export default function() { } +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`export default function() { } export default function f() { } export default class { } export default class C { } -export default 0;` +export default 0;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts index 8d22ea77c2b37..81877c8a98b33 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts @@ -18,7 +18,7 @@ // @Filename: /z.js // Normally -- just `export *` -/////*a*/module/*b*/.exports = require("./a"); +////module.exports = require("./a"); // If just a default is exported, just `export { default }` ////module.exports = require("./b"); // May need both @@ -28,12 +28,10 @@ // In untyped case just go with `export *` ////module.exports = require("./unknown"); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: +goTo.file("/z.js"); +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: `export * from "./a"; export { default } from "./b"; export * from "./c"; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts index 7b48bd5f91e23..84f081d24b3a3 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: /a.js -/////*a*/module/*b*/.exports = 0; +////module.exports = 0; // @Filename: /b.ts ////import a = require("./a"); @@ -11,12 +11,9 @@ // @Filename: /c.js ////const a = require("./a"); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `export default 0;`, +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: "export default 0;", }); goTo.file("/b.ts"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts index 8251f90fc0dee..b67d99e60e5c1 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts @@ -3,16 +3,22 @@ // @allowJs: true // @Filename: /a.js -/////*a*/exports/*b*/.f = function() {} +////exports.f = function() {}/*diagEnd*/ ////exports.C = class {} ////exports.x = 0; -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `export function f() { } +verify.getInfoDiagnostics([{ + message: "File is a CommonJS module; it may be converted to an ES6 module.", + start: 0, + length: test.marker("diagEnd").position, + category: "info", + code: 80001, +}]); + +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`export function f() { } export class C { } export const x = 0;`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts index a4b0ba24109af..dbd4e6a0a4cb2 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts @@ -3,15 +3,12 @@ // @allowJs: true // @Filename: /a.js -/////*a*/exports/*b*/.f = function g() { g(); } +////exports.f = function g() { g(); } ////exports.h = function h() { h(); } -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: `export const f = function g() { g(); }; -export function h() { h(); }` +export function h() { h(); }`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts index b18bc94579da6..61c46c98b3cf2 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: /a.js -/////*a*/module/*b*/.exports = { +////module.exports = { //// x: 0, //// f: function() {}, //// g: () => {}, @@ -11,12 +11,10 @@ //// C: class {}, ////}; -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `export const x = 0; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`export const x = 0; export function f() { } export function g() { } export function h() { } diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts index 05b4903eda385..f6fe10488203b 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts @@ -6,13 +6,11 @@ // @Filename: /a.js ////function f() {} -/////*a*/module/*b*/.exports = { f }; +////module.exports = { f }; -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `function f() {} +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`function f() {} export default { f };`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts index da9976fa7d06d..ff87d3c6948c2 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts @@ -7,7 +7,7 @@ ////exports.x; //// ////const y = 1; -/////*a*/exports/*b*/.y = y; +////exports.y = y; ////exports.y; //// ////exports.z = 2; @@ -15,12 +15,10 @@ //// exports.z; ////} -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `export const x = 0; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`export const x = 0; x; const y = 1; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts index b3b7fbf94c6c0..746524e849c85 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts @@ -3,15 +3,13 @@ // @allowJs: true // @Filename: /a.js -/////*a*/exports/*b*/.f = async function* f(p) {} +////exports.f = async function* f(p) {} ////exports.C = class C extends D { m() {} } -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `export async function* f(p) { } +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`export async function* f(p) { } export class C extends D { m() { } }`, diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts index b33b0a1a1609d..d7e857b5d5e41 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts @@ -5,11 +5,8 @@ // @Filename: /a.js ////const [x, y] = /*a*/require/*b*/("x"); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import _x from "x"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: `import _x from "x"; const [x, y] = _x;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts index 7c5415c145196..0e69f9519eec6 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts @@ -7,12 +7,10 @@ ////x(); ////x.y; -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import x, { y } from "x"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import x, { y } from "x"; x(); y;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts index 321a9cccf8b1b..a42f1fe5321d7 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts @@ -4,17 +4,15 @@ // @Filename: /a.js ////const x = require("x"); -////const [a, b] = /*a*/require/*b*/("x"); +////const [a, b] = require("x"); ////const {c, ...d} = require("x"); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import x from "x"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import x from "x"; import _x from "x"; const [a, b] = _x; import __x from "x"; -const { c, ...d } = __x;` +const { c, ...d } = __x;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts index 37d65ddc62261..3c45950c90d93 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts @@ -5,14 +5,12 @@ // @allowJs: true // @Filename: /a.js -////const x = /*a*/require/*b*/("x"), y = 0, { z } = require("z"); +////const x = require("x"), y = 0, { z } = require("z"); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import x from "x"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import x from "x"; const y = 0; import { z } from "z";`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts index 0c953b2e7e660..510b610315aa6 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts @@ -3,19 +3,17 @@ // @allowJs: true // @Filename: /a.js -////const [] = /*a0*/require/*b0*/("a-b"); -////const [] = /*a1*/require/*b1*/("0a"); -////const [] = /*a2*/require/*b2*/("1a"); +////const [] = require("a-b"); +////const [] = require("0a"); +////const [] = require("1a"); -goTo.select("a0", "b0"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import aB from "a-b"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import aB from "a-b"; const [] = aB; import A from "0a"; const [] = A; import _A from "1a"; -const [] = _A;` +const [] = _A;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts index f757db2164a89..32df990696490 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts @@ -3,13 +3,11 @@ // @allowJs: true // @Filename: /a.js -////const { x: { a, b } } = /*a*/require/*b*/("x"); +////const { x: { a, b } } = require("x"); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import x from "x"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import x from "x"; const { x: { a, b } } = x;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts index 474fd4b0f0fb4..4bff560e530c1 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts @@ -3,12 +3,9 @@ // @allowJs: true // @Filename: /a.js -////const { x, y: z } = /*a*/require/*b*/("x"); +////const { x, y: z } = require("x"); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: 'import { x, y as z } from "x";', +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: 'import { x, y as z } from "x";', }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts index bf7e207550e1e..7f66b67685e55 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts @@ -3,14 +3,12 @@ // @allowJs: true // @Filename: /a.js -////const x = /*a*/require/*b*/("x"); +////const x = require("x"); ////x.y; -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import { y } from "x"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import { y } from "x"; y;`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts index 57efd5370f28e..34c6ee6aa57f1 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts @@ -3,18 +3,16 @@ // @allowJs: true // @Filename: /a.js -////const x = /*a*/require/*b*/("x").default; +////const x = require("x").default; ////const a = require("b").c; ////const a = require("a").a; ////const [a, b] = require("c").d; ////const [a, b] = require("c").a; // Test that we avoid shadowing the earlier local variable 'a' from 'const [a,b] = d;'. -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import x from "x"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import x from "x"; import { c as a } from "b"; import { a } from "a"; import { d } from "c"; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts index c389280d75c7a..dec878599011b 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts @@ -3,16 +3,14 @@ // @allowJs: true // @Filename: /a.js -////const mod = /*a*/require/*b*/("mod"); +////const mod = require("mod"); ////const x = 0; ////mod.x(x); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: `import { x as _x } from "mod"; +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import { x as _x } from "mod"; const x = 0; -_x(x);` +_x(x);`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts index 2b81c816e20e4..f729f0a9815ad 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts @@ -7,10 +7,7 @@ // @Filename: /a.js /////*a*/require/*b*/("foo"); -goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Convert to ES6 module", - actionName: "Convert to ES6 module", - actionDescription: "Convert to ES6 module", - newContent: 'import "foo";', +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: 'import "foo";', }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts deleted file mode 100644 index 8d441f47dc382..0000000000000 --- a/tests/cases/fourslash/refactorConvertToEs6Module_triggers.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// - -// @allowJs: true - -// @Filename: /a.js -////c[|o|]nst [|a|]lias [|=|] [|m|]odule[|.|]export[|s|]; -////[|a|]lias[|.|][|x|] = 0; -////[|module.exports|]; -////[|require("x")|]; -////[|require("x").y;|]; - -goTo.eachRange(() => verify.refactorAvailable("Convert to ES6 module")); - diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_triggers_declarationList.ts b/tests/cases/fourslash/refactorConvertToEs6Module_triggers_declarationList.ts deleted file mode 100644 index 36ec32b0561e2..0000000000000 --- a/tests/cases/fourslash/refactorConvertToEs6Module_triggers_declarationList.ts +++ /dev/null @@ -1,9 +0,0 @@ -/// - -// @allowJs: true - -// @Filename: /a.js -////c[|o|]nst; -////require("x"); - -goTo.eachRange(() => verify.not.refactorAvailable("Convert to ES6 module")); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_triggers_noInitializer.ts b/tests/cases/fourslash/refactorConvertToEs6Module_triggers_noInitializer.ts deleted file mode 100644 index 23cbdd12aee26..0000000000000 --- a/tests/cases/fourslash/refactorConvertToEs6Module_triggers_noInitializer.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -// @allowJs: true - -// @Filename: /a.js -/////*a*/const/*b*/ alias; -////require("x"); - -goTo.select("a", "b"); -verify.not.refactorAvailable("Convert to ES6 module"); - From fb92a7ec602f75827a475d9ed77b2cbea2c58570 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 28 Feb 2018 08:06:54 -0800 Subject: [PATCH 2/2] Code review --- src/compiler/diagnosticMessages.json | 2 +- src/compiler/program.ts | 2 +- src/compiler/types.ts | 2 +- src/harness/fourslash.ts | 23 ++++------ src/harness/harnessLanguageService.ts | 4 +- src/harness/unittests/session.ts | 2 +- .../unittests/tsserverProjectSystem.ts | 10 ++--- src/server/client.ts | 8 ++-- src/server/protocol.ts | 21 ++++----- src/server/session.ts | 44 +++++++------------ src/services/codefixes/convertToEs6Module.ts | 3 +- src/services/services.ts | 8 ++-- src/services/shims.ts | 6 +-- ...iagnostics.ts => suggestionDiagnostics.ts} | 2 +- src/services/tsconfig.json | 2 +- src/services/types.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 26 +++++------ tests/baselines/reference/api/typescript.d.ts | 4 +- tests/cases/fourslash/fourslash.ts | 6 +-- tests/cases/fourslash/javascriptModules22.ts | 2 +- ...refactorConvertToEs6Module_export_named.ts | 4 +- 21 files changed, 76 insertions(+), 107 deletions(-) rename src/services/{infoDiagnostics.ts => suggestionDiagnostics.ts} (73%) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index edd9c6534a5ce..689d1079eefa8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3811,7 +3811,7 @@ }, "File is a CommonJS module; it may be converted to an ES6 module.": { - "category": "Info", + "category": "Suggestion", "code": 80001 }, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index aba70c7bdfa0a..aff5154abe000 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -255,7 +255,7 @@ namespace ts { switch (category) { case DiagnosticCategory.Error: return ForegroundColorEscapeSequences.Red; case DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow; - case DiagnosticCategory.Info: return Debug.fail("Should never get an Info diagnostic on the command line."); + case DiagnosticCategory.Suggestion: return Debug.fail("Should never get an Info diagnostic on the command line."); case DiagnosticCategory.Message: return ForegroundColorEscapeSequences.Blue; } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ca3f059d13b71..0942b13d782d2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4017,7 +4017,7 @@ namespace ts { export enum DiagnosticCategory { Warning, Error, - Info, + Suggestion, Message } /* @internal */ diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 0c08f9c63d4de..b244ac9d589ef 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -509,7 +509,7 @@ namespace FourSlash { return [ ...this.languageService.getSyntacticDiagnostics(fileName), ...this.languageService.getSemanticDiagnostics(fileName), - ...this.languageService.getInfoDiagnostics(fileName), + ...this.languageService.getSuggestionDiagnostics(fileName), ]; } @@ -581,11 +581,10 @@ namespace FourSlash { return "global"; } - public verifyNoErrors(options: FourSlashInterface.VerifyNoErrorsOptions) { + public verifyNoErrors() { ts.forEachKey(this.inputFiles, fileName => { if (!ts.isAnySupportedFileExtension(fileName)) return; - let errors = this.getDiagnostics(fileName); - if (options.ignoreInfoDiagnostics) errors = errors.filter(e => e.category !== ts.DiagnosticCategory.Info); + const errors = this.getDiagnostics(fileName).filter(e => e.category !== ts.DiagnosticCategory.Suggestion); if (errors.length) { this.printErrorLog(/*expectErrors*/ false, errors); const error = errors[0]; @@ -1250,8 +1249,8 @@ Actual: ${stringify(fullActual)}`); this.testDiagnostics(expected, diagnostics); } - public getInfoDiagnostics(expected: ReadonlyArray): void { - this.testDiagnostics(expected, this.languageService.getInfoDiagnostics(this.activeFile.fileName)); + public getSuggestionDiagnostics(expected: ReadonlyArray): void { + this.testDiagnostics(expected, this.languageService.getSuggestionDiagnostics(this.activeFile.fileName)); } private testDiagnostics(expected: ReadonlyArray, diagnostics: ReadonlyArray) { @@ -4146,8 +4145,8 @@ namespace FourSlashInterface { this.state.verifyCurrentSignatureHelpIs(expected); } - public noErrors(options: VerifyNoErrorsOptions = {}) { - this.state.verifyNoErrors(options); + public noErrors() { + this.state.verifyNoErrors(); } public numberOfErrorsInCurrentFile(expected: number) { @@ -4335,8 +4334,8 @@ namespace FourSlashInterface { this.state.getSemanticDiagnostics(expected); } - public getInfoDiagnostics(expected: ReadonlyArray) { - this.state.getInfoDiagnostics(expected); + public getSuggestionDiagnostics(expected: ReadonlyArray) { + this.state.getSuggestionDiagnostics(expected); } public ProjectInfo(expected: string[]) { @@ -4677,8 +4676,4 @@ namespace FourSlashInterface { source?: string; description: string; } - - export interface VerifyNoErrorsOptions { - ignoreInfoDiagnostics?: boolean; - } } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 4263f3fc1d89f..503246c72cad7 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -402,8 +402,8 @@ namespace Harness.LanguageService { getSemanticDiagnostics(fileName: string): ts.Diagnostic[] { return unwrapJSONCallResult(this.shim.getSemanticDiagnostics(fileName)); } - getInfoDiagnostics(fileName: string): ts.Diagnostic[] { - return unwrapJSONCallResult(this.shim.getInfoDiagnostics(fileName)); + getSuggestionDiagnostics(fileName: string): ts.Diagnostic[] { + return unwrapJSONCallResult(this.shim.getSuggestionDiagnostics(fileName)); } getCompilerOptionsDiagnostics(): ts.Diagnostic[] { return unwrapJSONCallResult(this.shim.getCompilerOptionsDiagnostics()); diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 50961840de216..b690045d7c1e5 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -216,7 +216,7 @@ namespace ts.server { CommandNames.GeterrForProject, CommandNames.SemanticDiagnosticsSync, CommandNames.SyntacticDiagnosticsSync, - CommandNames.InfoDiagnosticsSync, + CommandNames.SuggestionDiagnosticsSync, CommandNames.NavBar, CommandNames.NavBarFull, CommandNames.Navto, diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index a8b13f6035940..66f224d431e69 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -3080,7 +3080,7 @@ namespace ts.projectSystem { host.runQueuedImmediateCallbacks(1); assert.isFalse(hasError()); - checkErrorMessage(session, "infoDiag", { file: untitledFile, diagnostics: [] }); + checkErrorMessage(session, "suggestionDiag", { file: untitledFile, diagnostics: [] }); checkCompleteEvent(session, 2, expectedSequenceId); session.clearMessages(); } @@ -3144,7 +3144,7 @@ namespace ts.projectSystem { session.clearMessages(); host.runQueuedImmediateCallbacks(1); - checkErrorMessage(session, "infoDiag", { file: app.path, diagnostics: [] }); + checkErrorMessage(session, "suggestionDiag", { file: app.path, diagnostics: [] }); checkCompleteEvent(session, 2, expectedSequenceId); session.clearMessages(); } @@ -3953,7 +3953,7 @@ namespace ts.projectSystem { session.clearMessages(); host.runQueuedImmediateCallbacks(1); - checkErrorMessage(session, "infoDiag", { file: file1.path, diagnostics: [] }); + checkErrorMessage(session, "suggestionDiag", { file: file1.path, diagnostics: [] }); checkCompleteEvent(session, 2, expectedSequenceId); session.clearMessages(); @@ -4018,7 +4018,7 @@ namespace ts.projectSystem { host.runQueuedImmediateCallbacks(1); - checkErrorMessage(session, "infoDiag", { + checkErrorMessage(session, "suggestionDiag", { file: file.path, diagnostics: [ createDiagnostic({ line: 1, offset: 1 }, { line: 1, offset: 13 }, Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module) @@ -5227,7 +5227,7 @@ namespace ts.projectSystem { host.runQueuedImmediateCallbacks(1); assert.equal(host.getOutput().length, 2); const e3 = getMessage(0); - assert.equal(e3.event, "infoDiag"); + assert.equal(e3.event, "suggestionDiag"); verifyRequestCompleted(getErrId, 1); cancellationToken.resetToken(); diff --git a/src/server/client.ts b/src/server/client.ts index 2b41426911c92..6f04f14195730 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -348,13 +348,13 @@ namespace ts.server { getSemanticDiagnostics(file: string): Diagnostic[] { return this.getDiagnostics(file, CommandNames.SemanticDiagnosticsSync); } - getInfoDiagnostics(file: string): Diagnostic[] { - return this.getDiagnostics(file, CommandNames.InfoDiagnosticsSync); + getSuggestionDiagnostics(file: string): Diagnostic[] { + return this.getDiagnostics(file, CommandNames.SuggestionDiagnosticsSync); } private getDiagnostics(file: string, command: CommandNames) { - const request = this.processRequest(command, { file, includeLinePosition: true }); - const response = this.processResponse(request); + const request = this.processRequest(command, { file, includeLinePosition: true }); + const response = this.processResponse(request); return (response.body).map(entry => { const category = firstDefined(Object.keys(DiagnosticCategory), id => diff --git a/src/server/protocol.ts b/src/server/protocol.ts index f763f78bb94ff..40bee65e9f03e 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -42,7 +42,7 @@ namespace ts.server.protocol { GeterrForProject = "geterrForProject", SemanticDiagnosticsSync = "semanticDiagnosticsSync", SyntacticDiagnosticsSync = "syntacticDiagnosticsSync", - InfoDiagnosticsSync = "infoDiagnosticsSync", + SuggestionDiagnosticsSync = "suggestionDiagnosticsSync", NavBar = "navbar", /* @internal */ NavBarFull = "navbar-full", @@ -2011,18 +2011,13 @@ namespace ts.server.protocol { body?: Diagnostic[] | DiagnosticWithLinePosition[]; } - export interface InfoDiagnosticsSyncRequest extends FileRequest { - command: CommandTypes.InfoDiagnosticsSync; - arguments: InfoDiagnosticsSyncRequestArgs; + export interface SuggestionDiagnosticsSyncRequest extends FileRequest { + command: CommandTypes.SuggestionDiagnosticsSync; + arguments: SuggestionDiagnosticsSyncRequestArgs; } - export interface InfoDiagnosticsSyncRequestArgs extends FileRequestArgs { - includeLinePosition?: boolean; - } - - export interface InfoDiagnosticsSyncResponse extends Response { - body?: Diagnostic[] | DiagnosticWithLinePosition[]; - } + export type SuggestionDiagnosticsSyncRequestArgs = SemanticDiagnosticsSyncRequestArgs; + export type SuggestionDiagnosticsSyncResponse = SemanticDiagnosticsSyncResponse; /** * Synchronous request for syntactic diagnostics of one file. @@ -2135,7 +2130,7 @@ namespace ts.server.protocol { text: string; /** - * The category of the diagnostic message. This is the lower-case of a DiagnosticCategory member. + * The category of the diagnostic message, e.g. "error", "warning", or "suggestion". */ category: string; @@ -2169,7 +2164,7 @@ namespace ts.server.protocol { diagnostics: Diagnostic[]; } - export type DiagnosticEventKind = "semanticDiag" | "syntaxDiag" | "infoDiag"; + export type DiagnosticEventKind = "semanticDiag" | "syntaxDiag" | "suggestionDiag"; /** * Event message for DiagnosticEventKind event types. diff --git a/src/server/session.ts b/src/server/session.ts index 15fb40e3b0c9d..4f0981a388046 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -466,43 +466,29 @@ namespace ts.server { } private semanticCheck(file: NormalizedPath, project: Project) { - try { - const diags = isDeclarationFileInJSOnlyNonConfiguredProject(project, file) - ? emptyArray - : project.getLanguageService().getSemanticDiagnostics(file); - this.sendDiagnosticsEvent(file, project, diags, "semanticDiag"); - } - catch (err) { - this.logError(err, "semantic check"); - } + const diags = isDeclarationFileInJSOnlyNonConfiguredProject(project, file) + ? emptyArray + : project.getLanguageService().getSemanticDiagnostics(file); + this.sendDiagnosticsEvent(file, project, diags, "semanticDiag"); } private syntacticCheck(file: NormalizedPath, project: Project) { - try { - // TODO: why do we check for diagnostics existence here, but in semanticCheck send unconditionally? - const diagnostics = project.getLanguageService().getSyntacticDiagnostics(file); - if (diagnostics) { - this.sendDiagnosticsEvent(file, project, diagnostics, "syntaxDiag"); - } - } - catch (err) { - this.logError(err, "syntactic check"); - } + this.sendDiagnosticsEvent(file, project, project.getLanguageService().getSyntacticDiagnostics(file), "syntaxDiag"); } private infoCheck(file: NormalizedPath, project: Project) { + this.sendDiagnosticsEvent(file, project, project.getLanguageService().getSuggestionDiagnostics(file), "suggestionDiag"); + } + + private sendDiagnosticsEvent(file: NormalizedPath, project: Project, diagnostics: ReadonlyArray, kind: protocol.DiagnosticEventKind): void { try { - this.sendDiagnosticsEvent(file, project, project.getLanguageService().getInfoDiagnostics(file), "infoDiag"); + this.event({ file, diagnostics: diagnostics.map(diag => formatDiag(file, project, diag)) }, kind); } catch (err) { - this.logError(err, "info check"); + this.logError(err, kind); } } - private sendDiagnosticsEvent(file: NormalizedPath, project: Project, diagnostics: ReadonlyArray, kind: protocol.DiagnosticEventKind): void { - this.event({ file, diagnostics: diagnostics.map(diag => formatDiag(file, project, diag)) }, kind); - } - private updateErrorCheck(next: NextStep, checkList: PendingErrorCheck[], ms: number, requireOpen = true) { const seq = this.changeSeq; const followMs = Math.min(ms, 200); @@ -779,14 +765,14 @@ namespace ts.server { return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition); } - private getInfoDiagnosticsSync(args: protocol.InfoDiagnosticsSyncRequestArgs): ReadonlyArray | ReadonlyArray { + private getSuggestionDiagnosticsSync(args: protocol.SuggestionDiagnosticsSyncRequestArgs): ReadonlyArray | ReadonlyArray { const { configFile } = this.getConfigFileAndProject(args); if (configFile) { // Currently there are no info diagnostics for config files. return emptyArray; } // isSemantic because we don't want to info diagnostics in declaration files for JS-only users - return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getInfoDiagnostics(file), args.includeLinePosition); + return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSuggestionDiagnostics(file), args.includeLinePosition); } private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { @@ -1986,8 +1972,8 @@ namespace ts.server { [CommandNames.SyntacticDiagnosticsSync]: (request: protocol.SyntacticDiagnosticsSyncRequest) => { return this.requiredResponse(this.getSyntacticDiagnosticsSync(request.arguments)); }, - [CommandNames.InfoDiagnosticsSync]: (request: protocol.InfoDiagnosticsSyncRequest) => { - return this.requiredResponse(this.getInfoDiagnosticsSync(request.arguments)); + [CommandNames.SuggestionDiagnosticsSync]: (request: protocol.SuggestionDiagnosticsSyncRequest) => { + return this.requiredResponse(this.getSuggestionDiagnosticsSync(request.arguments)); }, [CommandNames.Geterr]: (request: protocol.GeterrRequest) => { this.errorCheck.startNew(next => this.getDiagnostics(next, request.arguments.delay, request.arguments.files)); diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index dfd8ff10b420a..d494e5c907f73 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -1,8 +1,7 @@ /* @internal */ namespace ts.codefix { - const errorCodes = [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module.code]; registerCodeFix({ - errorCodes, + errorCodes: [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module.code], getCodeActions(context) { const description = getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module); const { sourceFile, program } = context; diff --git a/src/services/services.ts b/src/services/services.ts index 31633fcb184f7..e29633a92e038 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -10,7 +10,6 @@ /// /// /// -/// /// /// /// @@ -21,6 +20,7 @@ /// /// /// +/// /// /// /// @@ -1420,9 +1420,9 @@ namespace ts { return [...semanticDiagnostics, ...declarationDiagnostics]; } - function getInfoDiagnostics(fileName: string): Diagnostic[] { + function getSuggestionDiagnostics(fileName: string): Diagnostic[] { synchronizeHostData(); - return infoDiagnostics(getValidSourceFile(fileName)); + return computeSuggestionDiagnostics(getValidSourceFile(fileName)); } function getCompilerOptionsDiagnostics() { @@ -2107,7 +2107,7 @@ namespace ts { cleanupSemanticCache, getSyntacticDiagnostics, getSemanticDiagnostics, - getInfoDiagnostics, + getSuggestionDiagnostics, getCompilerOptionsDiagnostics, getSyntacticClassifications, getSemanticClassifications, diff --git a/src/services/shims.ts b/src/services/shims.ts index 66e74ee97e6a6..5d3f82eb9666c 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -144,7 +144,7 @@ namespace ts { getSyntacticDiagnostics(fileName: string): string; getSemanticDiagnostics(fileName: string): string; - getInfoDiagnostics(fileName: string): string; + getSuggestionDiagnostics(fileName: string): string; getCompilerOptionsDiagnostics(): string; getSyntacticClassifications(fileName: string, start: number, length: number): string; @@ -716,8 +716,8 @@ namespace ts { }); } - public getInfoDiagnostics(fileName: string): string { - return this.forwardJSONCall(`getInfoDiagnostics('${fileName}')`, () => this.realizeDiagnostics(this.languageService.getInfoDiagnostics(fileName))); + public getSuggestionDiagnostics(fileName: string): string { + return this.forwardJSONCall(`getSuggestionDiagnostics('${fileName}')`, () => this.realizeDiagnostics(this.languageService.getSuggestionDiagnostics(fileName))); } public getCompilerOptionsDiagnostics(): string { diff --git a/src/services/infoDiagnostics.ts b/src/services/suggestionDiagnostics.ts similarity index 73% rename from src/services/infoDiagnostics.ts rename to src/services/suggestionDiagnostics.ts index 8d0493d34af7a..8cb26f74a01ee 100644 --- a/src/services/infoDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -1,6 +1,6 @@ /* @internal */ namespace ts { - export function infoDiagnostics(sourceFile: SourceFile): Diagnostic[] { + export function computeSuggestionDiagnostics(sourceFile: SourceFile): Diagnostic[] { return sourceFile.commonJsModuleIndicator ? [createDiagnosticForNode(sourceFile.commonJsModuleIndicator, Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module)] : emptyArray; diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index a3e5deb59f2d1..686c3357bc3b9 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -53,7 +53,6 @@ "documentRegistry.ts", "findAllReferences.ts", "importTracker.ts", - "infoDiagnostics.ts", "goToDefinition.ts", "jsDoc.ts", "jsTyping.ts", @@ -71,6 +70,7 @@ "semver.ts", "shims.ts", "signatureHelp.ts", + "suggestionDiagnostics.ts", "symbolDisplay.ts", "textChanges.ts", "refactorProvider.ts", diff --git a/src/services/types.ts b/src/services/types.ts index 7b5ecd1ca69d9..dba10960cdf76 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -223,7 +223,7 @@ namespace ts { getSyntacticDiagnostics(fileName: string): Diagnostic[]; getSemanticDiagnostics(fileName: string): Diagnostic[]; - getInfoDiagnostics(fileName: string): Diagnostic[]; + getSuggestionDiagnostics(fileName: string): Diagnostic[]; // TODO: Rename this to getProgramDiagnostics to better indicate that these are any // diagnostics present for the program level, and not just 'options' diagnostics. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 719771b831df4..23af7487675c0 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2262,7 +2262,7 @@ declare namespace ts { enum DiagnosticCategory { Warning = 0, Error = 1, - Info = 2, + Suggestion = 2, Message = 3, } enum ModuleResolutionKind { @@ -4055,7 +4055,7 @@ declare namespace ts { cleanupSemanticCache(): void; getSyntacticDiagnostics(fileName: string): Diagnostic[]; getSemanticDiagnostics(fileName: string): Diagnostic[]; - getInfoDiagnostics(fileName: string): Diagnostic[]; + getSuggestionDiagnostics(fileName: string): Diagnostic[]; getCompilerOptionsDiagnostics(): Diagnostic[]; /** * @deprecated Use getEncodedSyntacticClassifications instead. @@ -5026,7 +5026,7 @@ declare namespace ts.server.protocol { GeterrForProject = "geterrForProject", SemanticDiagnosticsSync = "semanticDiagnosticsSync", SyntacticDiagnosticsSync = "syntacticDiagnosticsSync", - InfoDiagnosticsSync = "infoDiagnosticsSync", + SuggestionDiagnosticsSync = "suggestionDiagnosticsSync", NavBar = "navbar", Navto = "navto", NavTree = "navtree", @@ -6549,16 +6549,12 @@ declare namespace ts.server.protocol { interface SemanticDiagnosticsSyncResponse extends Response { body?: Diagnostic[] | DiagnosticWithLinePosition[]; } - interface InfoDiagnosticsSyncRequest extends FileRequest { - command: CommandTypes.InfoDiagnosticsSync; - arguments: InfoDiagnosticsSyncRequestArgs; - } - interface InfoDiagnosticsSyncRequestArgs extends FileRequestArgs { - includeLinePosition?: boolean; - } - interface InfoDiagnosticsSyncResponse extends Response { - body?: Diagnostic[] | DiagnosticWithLinePosition[]; + interface SuggestionDiagnosticsSyncRequest extends FileRequest { + command: CommandTypes.SuggestionDiagnosticsSync; + arguments: SuggestionDiagnosticsSyncRequestArgs; } + type SuggestionDiagnosticsSyncRequestArgs = SemanticDiagnosticsSyncRequestArgs; + type SuggestionDiagnosticsSyncResponse = SemanticDiagnosticsSyncResponse; /** * Synchronous request for syntactic diagnostics of one file. */ @@ -6655,7 +6651,7 @@ declare namespace ts.server.protocol { */ text: string; /** - * The category of the diagnostic message. This is the lower-case of a DiagnosticCategory member. + * The category of the diagnostic message, e.g. "error", "warning", or "suggestion". */ category: string; /** @@ -6683,7 +6679,7 @@ declare namespace ts.server.protocol { */ diagnostics: Diagnostic[]; } - type DiagnosticEventKind = "semanticDiag" | "syntaxDiag" | "infoDiag"; + type DiagnosticEventKind = "semanticDiag" | "syntaxDiag" | "suggestionDiag"; /** * Event message for DiagnosticEventKind event types. * These events provide syntactic and semantic errors for a file. @@ -7242,7 +7238,7 @@ declare namespace ts.server { private getOccurrences(args); private getSyntacticDiagnosticsSync(args); private getSemanticDiagnosticsSync(args); - private getInfoDiagnosticsSync(args); + private getSuggestionDiagnosticsSync(args); private getDocumentHighlights(args, simplifiedResult); private setCompilerOptionsForInferredProjects(args); private getProjectInfo(args); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8e48c67c24e72..ab4e3aeff8c26 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2262,7 +2262,7 @@ declare namespace ts { enum DiagnosticCategory { Warning = 0, Error = 1, - Info = 2, + Suggestion = 2, Message = 3, } enum ModuleResolutionKind { @@ -4307,7 +4307,7 @@ declare namespace ts { cleanupSemanticCache(): void; getSyntacticDiagnostics(fileName: string): Diagnostic[]; getSemanticDiagnostics(fileName: string): Diagnostic[]; - getInfoDiagnostics(fileName: string): Diagnostic[]; + getSuggestionDiagnostics(fileName: string): Diagnostic[]; getCompilerOptionsDiagnostics(): Diagnostic[]; /** * @deprecated Use getEncodedSyntacticClassifications instead. diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 47f78782df194..7561ca3793d59 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -282,9 +282,7 @@ declare namespace FourSlashInterface { currentSignatureTypeParameterCountIs(expected: number): void; currentSignatureHelpIs(expected: string): void; // Checks that there are no compile errors. - noErrors(options?: { - ignoreInfoDiagnostics?: boolean, - }): void; + noErrors(): void; numberOfErrorsInCurrentFile(expected: number): void; baselineCurrentFileBreakpointLocations(): void; baselineCurrentFileNameOrDottedNameSpans(): void; @@ -351,7 +349,7 @@ declare namespace FourSlashInterface { }, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[]): void; getSyntacticDiagnostics(expected: ReadonlyArray): void; getSemanticDiagnostics(expected: ReadonlyArray): void; - getInfoDiagnostics(expected: ReadonlyArray): void; + getSuggestionDiagnostics(expected: ReadonlyArray): void; ProjectInfo(expected: string[]): void; allRangesAppearInImplementationList(markerName: string): void; } diff --git a/tests/cases/fourslash/javascriptModules22.ts b/tests/cases/fourslash/javascriptModules22.ts index 5e68f86abbc13..caa8c6798b19d 100644 --- a/tests/cases/fourslash/javascriptModules22.ts +++ b/tests/cases/fourslash/javascriptModules22.ts @@ -29,4 +29,4 @@ verify.completionListContains("name"); edit.insert("name;\nsausages."); verify.completionListContains("eggs"); edit.insert("eggs;"); -verify.noErrors({ ignoreInfoDiagnostics: true }); +verify.noErrors(); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts index b67d99e60e5c1..03303b1e09e3f 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts @@ -7,11 +7,11 @@ ////exports.C = class {} ////exports.x = 0; -verify.getInfoDiagnostics([{ +verify.getSuggestionDiagnostics([{ message: "File is a CommonJS module; it may be converted to an ES6 module.", start: 0, length: test.marker("diagEnd").position, - category: "info", + category: "suggestion", code: 80001, }]);