From 344d928546feee23a5483d52cbc24ea5213694a7 Mon Sep 17 00:00:00 2001 From: kieferrm Date: Wed, 21 Mar 2018 15:36:41 -0700 Subject: [PATCH 1/2] support for multi-location diagnostics --- client/package.json | 2 +- client/src/client.ts | 5 +++-- client/src/protocolConverter.ts | 9 +++++++++ protocol/src/protocol.ts | 9 +++++++-- types/src/main.ts | 30 ++++++++++++++++++++++++++++-- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/client/package.json b/client/package.json index 87fe4f35f..ada958b4c 100644 --- a/client/package.json +++ b/client/package.json @@ -5,7 +5,7 @@ "author": "Microsoft Corporation", "license": "MIT", "engines": { - "vscode": "^1.20" + "vscode": "^1.22" }, "repository": { "type": "git", diff --git a/client/src/client.ts b/client/src/client.ts index ae8af4bba..46e900cc9 100644 --- a/client/src/client.ts +++ b/client/src/client.ts @@ -57,7 +57,7 @@ import { } from 'vscode-languageserver-protocol'; import { ColorProviderMiddleware } from './colorProvider'; -import { ImplementationMiddleware } from './implementation' +import { ImplementationMiddleware } from './implementation' import { TypeDefinitionMiddleware } from './typeDefinition'; import { ConfigurationWorkspaceMiddleware } from './configuration'; import { WorkspaceFolderWorkspaceMiddleware } from './workspaceFolders'; @@ -2659,7 +2659,7 @@ export abstract class BaseLanguageClient { }); } - private _clientGetRootPath(): string | undefined{ + private _clientGetRootPath(): string | undefined { let folders = Workspace.workspaceFolders; if (!folders || folders.length === 0) { return undefined; @@ -2904,6 +2904,7 @@ export abstract class BaseLanguageClient { let result: ClientCapabilities = {}; ensure(result, 'workspace')!.applyEdit = true; ensure(ensure(result, 'workspace')!, 'workspaceEdit')!.documentChanges = true; + result.diagnosticRelatedInformation = true; for (let feature of this._features) { feature.fillClientCapabilities(result); } diff --git a/client/src/protocolConverter.ts b/client/src/protocolConverter.ts index 016fa24cd..563209b02 100644 --- a/client/src/protocolConverter.ts +++ b/client/src/protocolConverter.ts @@ -144,9 +144,18 @@ export function createConverter(uriConverter?: URIConverter): Converter { let result = new code.Diagnostic(asRange(diagnostic.range), diagnostic.message, asDiagnosticSeverity(diagnostic.severity)); if (Is.number(diagnostic.code) || Is.string(diagnostic.code)) { result.code = diagnostic.code; } if (diagnostic.source) { result.source = diagnostic.source; } + if (diagnostic.relatedInformation) { result.relatedInformation = asRelatedInformation(diagnostic.relatedInformation); } return result; } + function asRelatedInformation(relatedInformation: ls.DiagnosticRelatedInformation[]): code.DiagnosticRelatedInformation[] { + return relatedInformation.map(asDiagnosticRelatedInformation); + } + + function asDiagnosticRelatedInformation(information: ls.DiagnosticRelatedInformation): code.DiagnosticRelatedInformation { + return new code.DiagnosticRelatedInformation(asLocation(information.location), information.message); + } + function asPosition(value: undefined | null): undefined; function asPosition(value: ls.Position): code.Position; function asPosition(value: ls.Position | undefined | null): code.Position | undefined; diff --git a/protocol/src/protocol.ts b/protocol/src/protocol.ts index ee411cc21..946155a3c 100644 --- a/protocol/src/protocol.ts +++ b/protocol/src/protocol.ts @@ -19,7 +19,7 @@ import { } from 'vscode-languageserver-types'; import { ImplementationRequest, ImplementationClientCapabilities, ImplementationServerCapabilities } from './protocol.implementation'; -import { TypeDefinitionRequest, TypeDefinitionClientCapabilities, TypeDefinitionServerCapabilities } from './protocol.typeDefinition'; +import { TypeDefinitionRequest, TypeDefinitionClientCapabilities, TypeDefinitionServerCapabilities } from './protocol.typeDefinition'; import { WorkspaceFoldersRequest, DidChangeWorkspaceFoldersNotification, DidChangeWorkspaceFoldersParams, WorkspaceFolder, WorkspaceFoldersChangeEvent, WorkspaceFoldersInitializeParams, WorkspaceFoldersClientCapabilities, WorkspaceFoldersServerCapabilities @@ -28,7 +28,7 @@ import { ConfigurationRequest, ConfigurationParams, ConfigurationItem, Configura import { DocumentColorRequest, ColorPresentationRequest, ColorProviderOptions, DocumentColorParams, ColorPresentationParams, Color, ColorInformation, ColorPresentation, ColorServerCapabilities, ColorClientCapabilities, - } from './protocol.colorProvider'; +} from './protocol.colorProvider'; /** * A document filter denotes a document by different properties like @@ -502,6 +502,11 @@ export interface _ClientCapabilities { */ textDocument?: TextDocumentClientCapabilities; + /** + * Whether the client supports diagnostics with related information. + */ + diagnosticRelatedInformation?: boolean; + /** * Experimental client capabilities. */ diff --git a/types/src/main.ts b/types/src/main.ts index 0b7cc06ee..a2c8ef0df 100644 --- a/types/src/main.ts +++ b/types/src/main.ts @@ -205,6 +205,20 @@ export interface Diagnostic { * The diagnostic's message. */ message: string; + + /** + * Array of information related to this diagnostic. + */ + relatedInformation?: DiagnosticRelatedInformation[]; +} + +/** + * Represents a supplemental information of a diagnostic, such + * as other locations that are relevant for a compiler error or warning. + */ +export interface DiagnosticRelatedInformation { + location: Location, + message: string } /** @@ -215,7 +229,7 @@ export namespace Diagnostic { /** * Creates a new Diagnostic literal. */ - export function create(range: Range, message: string, severity?: DiagnosticSeverity, code?: number | string, source?: string): Diagnostic { + export function create(range: Range, message: string, severity?: DiagnosticSeverity, code?: number | string, source?: string, relatedInformation?: DiagnosticRelatedInformation[]): Diagnostic { let result: Diagnostic = { range, message }; if (Is.defined(severity)) { result.severity = severity; @@ -226,8 +240,12 @@ export namespace Diagnostic { if (Is.defined(source)) { result.source = source; } + if (Is.defined(relatedInformation)) { + result.relatedInformation = relatedInformation; + } return result; } + /** * Checks whether the given literal conforms to the [Diagnostic](#Diagnostic) interface. */ @@ -238,7 +256,15 @@ export namespace Diagnostic { && Is.string(candidate.message) && (Is.number(candidate.severity) || Is.undefined(candidate.severity)) && (Is.number(candidate.code) || Is.string(candidate.code) || Is.undefined(candidate.code)) - && (Is.string(candidate.source) || Is.undefined(candidate.source)); + && (Is.string(candidate.source) || Is.undefined(candidate.source)) + && (Is.typedArray(candidate.relatedInformation, isRelatedInformation) || Is.undefined(candidate.relatedInformation)); + } + + function isRelatedInformation(value: any): value is DiagnosticRelatedInformation { + let candidate = value as DiagnosticRelatedInformation; + return Is.defined(candidate) + && Location.is(candidate.location) + && Is.string(candidate.message); } } From 99ca10bb8340f9d0db174320b95044a673d8e02c Mon Sep 17 00:00:00 2001 From: kieferrm Date: Wed, 28 Mar 2018 11:15:58 -0700 Subject: [PATCH 2/2] move capability to to textDocument --- client/src/client.ts | 2 +- protocol/src/protocol.ts | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/client/src/client.ts b/client/src/client.ts index 46e900cc9..e71eee972 100644 --- a/client/src/client.ts +++ b/client/src/client.ts @@ -2904,7 +2904,7 @@ export abstract class BaseLanguageClient { let result: ClientCapabilities = {}; ensure(result, 'workspace')!.applyEdit = true; ensure(ensure(result, 'workspace')!, 'workspaceEdit')!.documentChanges = true; - result.diagnosticRelatedInformation = true; + ensure(ensure(result, 'textDocument')!, 'publishDiagnostics')!.relatedInformation = true; for (let feature of this._features) { feature.fillClientCapabilities(result); } diff --git a/protocol/src/protocol.ts b/protocol/src/protocol.ts index 946155a3c..8abb9090c 100644 --- a/protocol/src/protocol.ts +++ b/protocol/src/protocol.ts @@ -263,7 +263,7 @@ export interface TextDocumentClientCapabilities { * The client supports did save notifications. */ didSave?: boolean; - } + }; /** * Capabilities specific to the `textDocument/completion` @@ -486,6 +486,16 @@ export interface TextDocumentClientCapabilities { */ dynamicRegistration?: boolean; }; + + /** + * Capabilities specific to `textDocument/publishDiagnostics`. + */ + publishDiagnostics?: { + /** + * Whether the clients accepts diagnostics with related information. + */ + relatedInformation?: boolean; + }; } /** @@ -502,11 +512,6 @@ export interface _ClientCapabilities { */ textDocument?: TextDocumentClientCapabilities; - /** - * Whether the client supports diagnostics with related information. - */ - diagnosticRelatedInformation?: boolean; - /** * Experimental client capabilities. */