Skip to content

Commit 8d02227

Browse files
committed
add DiagnosticRelatedInformation, microsoft#10271
1 parent 16e8273 commit 8d02227

7 files changed

Lines changed: 113 additions & 32 deletions

File tree

src/vs/vscode.d.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3674,6 +3674,32 @@ declare module 'vscode' {
36743674
Hint = 3
36753675
}
36763676

3677+
/**
3678+
* Represents a related message and source code location for a diagnostic. This should be
3679+
* used to point to code locations that cause or related to a diagnostics, e.g when duplicating
3680+
* a symbol in a scope.
3681+
*/
3682+
export class DiagnosticRelatedInformation {
3683+
3684+
/**
3685+
* The location of this related diagnostic information.
3686+
*/
3687+
location: Location;
3688+
3689+
/**
3690+
* The message of this related diagnostic information.
3691+
*/
3692+
message: string;
3693+
3694+
/**
3695+
* Creates a new related diagnostic information object.
3696+
*
3697+
* @param location The location.
3698+
* @param message The message.
3699+
*/
3700+
constructor(location: Location, message: string);
3701+
}
3702+
36773703
/**
36783704
* Represents a diagnostic, such as a compiler error or warning. Diagnostic objects
36793705
* are only valid in the scope of a file.
@@ -3708,6 +3734,12 @@ declare module 'vscode' {
37083734
*/
37093735
code: string | number;
37103736

3737+
/**
3738+
* An array of related diagnostic information, e.g. when symbol-names within
3739+
* a scope collide all definitions can be marked via this property.
3740+
*/
3741+
relatedInformation: DiagnosticRelatedInformation[];
3742+
37113743
/**
37123744
* Creates a new diagnostic object.
37133745
*

src/vs/workbench/api/node/extHost.api.impl.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ export function createApiFactory(
599599
CompletionTriggerKind: extHostTypes.CompletionTriggerKind,
600600
DebugAdapterExecutable: extHostTypes.DebugAdapterExecutable,
601601
Diagnostic: extHostTypes.Diagnostic,
602+
DiagnosticRelatedInformation: extHostTypes.DiagnosticRelatedInformation,
602603
DiagnosticSeverity: extHostTypes.DiagnosticSeverity,
603604
Disposable: extHostTypes.Disposable,
604605
DocumentHighlight: extHostTypes.DocumentHighlight,

src/vs/workbench/api/node/extHostDiagnostics.ts

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import URI from 'vs/base/common/uri';
1010
import * as vscode from 'vscode';
1111
import { MainContext, MainThreadDiagnosticsShape, ExtHostDiagnosticsShape, IMainContext } from './extHost.protocol';
1212
import { DiagnosticSeverity } from './extHostTypes';
13+
import * as converter from './extHostTypeConverters';
1314
import { mergeSort } from 'vs/base/common/arrays';
1415
import { Event, Emitter, debounceEvent, mapEvent } from 'vs/base/common/event';
1516
import { keys } from 'vs/base/common/map';
@@ -115,7 +116,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
115116
orderLoop: for (let i = 0; i < 4; i++) {
116117
for (let diagnostic of diagnostics) {
117118
if (diagnostic.severity === order[i]) {
118-
const len = marker.push(DiagnosticCollection.toMarkerData(diagnostic));
119+
const len = marker.push(converter.fromDiagnostic(diagnostic));
119120
if (len === DiagnosticCollection._maxDiagnosticsPerFile) {
120121
break orderLoop;
121122
}
@@ -133,7 +134,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
133134
endColumn: marker[marker.length - 1].endColumn
134135
});
135136
} else {
136-
marker = diagnostics.map(DiagnosticCollection.toMarkerData);
137+
marker = diagnostics.map(converter.fromDiagnostic);
137138
}
138139
}
139140

@@ -185,32 +186,6 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
185186
}
186187
}
187188

188-
public static toMarkerData(diagnostic: vscode.Diagnostic): IMarkerData {
189-
190-
let range = diagnostic.range;
191-
192-
return <IMarkerData>{
193-
startLineNumber: range.start.line + 1,
194-
startColumn: range.start.character + 1,
195-
endLineNumber: range.end.line + 1,
196-
endColumn: range.end.character + 1,
197-
message: diagnostic.message,
198-
source: diagnostic.source,
199-
severity: DiagnosticCollection._convertDiagnosticsSeverity(diagnostic.severity),
200-
code: String(diagnostic.code)
201-
};
202-
}
203-
204-
private static _convertDiagnosticsSeverity(severity: number): MarkerSeverity {
205-
switch (severity) {
206-
case 0: return MarkerSeverity.Error;
207-
case 1: return MarkerSeverity.Warning;
208-
case 2: return MarkerSeverity.Info;
209-
case 3: return MarkerSeverity.Hint;
210-
default: return MarkerSeverity.Error;
211-
}
212-
}
213-
214189
private static _compareIndexedTuplesByUri(a: [vscode.Uri, vscode.Diagnostic[]], b: [vscode.Uri, vscode.Diagnostic[]]): number {
215190
if (a[0].toString() < b[0].toString()) {
216191
return -1;

src/vs/workbench/api/node/extHostLanguageFeatures.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import * as modes from 'vs/editor/common/modes';
1515
import { ExtHostHeapService } from 'vs/workbench/api/node/extHostHeapService';
1616
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
1717
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
18-
import { ExtHostDiagnostics, DiagnosticCollection } from 'vs/workbench/api/node/extHostDiagnostics';
18+
import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
1919
import { asWinJsPromise } from 'vs/base/common/async';
2020
import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, SymbolInformationDto, SuggestResultDto, WorkspaceSymbolsDto, SuggestionDto, CodeActionDto } from './extHost.protocol';
2121
import { regExpLeadsToEndlessLoop } from 'vs/base/common/strings';
@@ -313,7 +313,7 @@ class CodeActionAdapter {
313313
result.push({
314314
title: candidate.title,
315315
command: candidate.command && this._commands.toInternal(candidate.command),
316-
diagnostics: candidate.diagnostics && candidate.diagnostics.map(DiagnosticCollection.toMarkerData),
316+
diagnostics: candidate.diagnostics && candidate.diagnostics.map(TypeConverters.fromDiagnostic),
317317
edit: candidate.edit && TypeConverters.WorkspaceEdit.from(candidate.edit),
318318
kind: candidate.kind && candidate.kind.value
319319
});

src/vs/workbench/api/node/extHostTypeConverters.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import * as htmlContent from 'vs/base/common/htmlContent';
2020
import { IRelativePattern } from 'vs/base/common/glob';
2121
import { LanguageSelector, LanguageFilter } from 'vs/editor/common/modes/languageSelector';
2222
import { WorkspaceEditDto, ResourceTextEditDto } from 'vs/workbench/api/node/extHost.protocol';
23-
import { MarkerSeverity } from 'vs/platform/markers/common/markers';
23+
import { MarkerSeverity, IRelatedInformation, IMarkerData } from 'vs/platform/markers/common/markers';
2424

2525
export interface PositionLike {
2626
line: number;
@@ -83,6 +83,30 @@ export function fromPosition(position: types.Position): IPosition {
8383
return { lineNumber: position.line + 1, column: position.character + 1 };
8484
}
8585

86+
87+
export function fromDiagnostic(value: vscode.Diagnostic): IMarkerData {
88+
return {
89+
...fromRange(value.range),
90+
message: value.message,
91+
source: value.source,
92+
code: String(value.code),
93+
severity: fromDiagnosticSeverity(value.severity),
94+
relatedInformation: value.relatedInformation && value.relatedInformation.map(fromDiagnosticRelatedInformation)
95+
};
96+
}
97+
98+
export function fromDiagnosticRelatedInformation(value: types.DiagnosticRelatedInformation): IRelatedInformation {
99+
return {
100+
...fromRange(value.location.range),
101+
message: value.message,
102+
resource: value.location.uri
103+
};
104+
}
105+
106+
export function toDiagnosticRelatedInformation(value: IRelatedInformation): types.DiagnosticRelatedInformation {
107+
return new types.DiagnosticRelatedInformation(new types.Location(value.resource, toRange(value)), value.message);
108+
}
109+
86110
export function fromDiagnosticSeverity(value: number): MarkerSeverity {
87111
switch (value) {
88112
case types.DiagnosticSeverity.Error:
@@ -111,6 +135,7 @@ export function toDiagnosticSeverty(value: MarkerSeverity): types.DiagnosticSeve
111135
return types.DiagnosticSeverity.Error;
112136
}
113137

138+
114139
export function fromViewColumn(column?: vscode.ViewColumn): EditorPosition {
115140
let editorColumn = EditorPosition.ONE;
116141
if (typeof column !== 'number') {

src/vs/workbench/api/node/extHostTypes.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,13 +728,35 @@ export class Location {
728728
}
729729
}
730730

731+
export class DiagnosticRelatedInformation {
732+
733+
static is(thing: any): thing is DiagnosticRelatedInformation {
734+
if (!thing) {
735+
return false;
736+
}
737+
return typeof (<DiagnosticRelatedInformation>thing).message === 'string'
738+
&& (<DiagnosticRelatedInformation>thing).location
739+
&& Range.isRange((<DiagnosticRelatedInformation>thing).location.range)
740+
&& URI.isUri((<DiagnosticRelatedInformation>thing).location.uri);
741+
}
742+
743+
location: Location;
744+
message: string;
745+
746+
constructor(location: Location, message: string) {
747+
this.location = location;
748+
this.message = message;
749+
}
750+
}
751+
731752
export class Diagnostic {
732753

733754
range: Range;
734755
message: string;
735756
source: string;
736757
code: string | number;
737758
severity: DiagnosticSeverity;
759+
relatedInformation: DiagnosticRelatedInformation[];
738760

739761
constructor(range: Range, message: string, severity: DiagnosticSeverity = DiagnosticSeverity.Error) {
740762
this.range = range;

src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import * as assert from 'assert';
99
import URI, { UriComponents } from 'vs/base/common/uri';
1010
import { DiagnosticCollection } from 'vs/workbench/api/node/extHostDiagnostics';
11-
import { Diagnostic, DiagnosticSeverity, Range } from 'vs/workbench/api/node/extHostTypes';
11+
import { Diagnostic, DiagnosticSeverity, Range, DiagnosticRelatedInformation, Location } from 'vs/workbench/api/node/extHostTypes';
1212
import { MainThreadDiagnosticsShape } from 'vs/workbench/api/node/extHost.protocol';
1313
import { IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers';
1414
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
@@ -298,4 +298,30 @@ suite('ExtHostDiagnostics', () => {
298298
collection.clear();
299299
await p;
300300
});
301+
302+
test('diagnostics with related information', function (done) {
303+
304+
let collection = new DiagnosticCollection('ddd', new class extends DiagnosticsShape {
305+
$changeMany(owner: string, entries: [UriComponents, IMarkerData[]][]) {
306+
307+
let [[, data]] = entries;
308+
assert.equal(entries.length, 1);
309+
assert.equal(data.length, 1);
310+
311+
let [diag] = data;
312+
assert.equal(diag.relatedInformation.length, 2);
313+
assert.equal(diag.relatedInformation[0].message, 'more1');
314+
assert.equal(diag.relatedInformation[1].message, 'more2');
315+
done();
316+
}
317+
}, new Emitter<any>());
318+
319+
let diag = new Diagnostic(new Range(0, 0, 1, 1), 'Foo');
320+
diag.relatedInformation = [
321+
new DiagnosticRelatedInformation(new Location(URI.parse('cc:dd'), new Range(0, 0, 0, 0)), 'more1'),
322+
new DiagnosticRelatedInformation(new Location(URI.parse('cc:ee'), new Range(0, 0, 0, 0)), 'more2')
323+
];
324+
325+
collection.set(URI.parse('aa:bb'), [diag]);
326+
});
301327
});

0 commit comments

Comments
 (0)