mirror of
https://github.com/Microsoft/vscode
synced 2024-10-01 08:50:48 +00:00
[typescript-language-features] Region-based semantic diagnostics for TypeScript (#208713)
* WIP * invalidate diagnostics in range * check whether should use region based diagnostics * add ts-expect-errors * make region opt off by default * bump to expected 5.6 * update comments to refer to 5.6 * make region diagnostics on by default for insiders
This commit is contained in:
parent
7717059b2e
commit
878af0771b
|
@ -1315,6 +1315,12 @@
|
||||||
"markdownDescription": "%typescript.workspaceSymbols.excludeLibrarySymbols%",
|
"markdownDescription": "%typescript.workspaceSymbols.excludeLibrarySymbols%",
|
||||||
"scope": "window"
|
"scope": "window"
|
||||||
},
|
},
|
||||||
|
"typescript.tsserver.enableRegionDiagnostics": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"description": "%typescript.tsserver.enableRegionDiagnostics%",
|
||||||
|
"scope": "window"
|
||||||
|
},
|
||||||
"javascript.experimental.updateImportsOnPaste": {
|
"javascript.experimental.updateImportsOnPaste": {
|
||||||
"scope": "window",
|
"scope": "window",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
"typescript.tsserver.pluginPaths": "Additional paths to discover TypeScript Language Service plugins.",
|
"typescript.tsserver.pluginPaths": "Additional paths to discover TypeScript Language Service plugins.",
|
||||||
"typescript.tsserver.pluginPaths.item": "Either an absolute or relative path. Relative path will be resolved against workspace folder(s).",
|
"typescript.tsserver.pluginPaths.item": "Either an absolute or relative path. Relative path will be resolved against workspace folder(s).",
|
||||||
"typescript.tsserver.trace": "Enables tracing of messages sent to the TS server. This trace can be used to diagnose TS Server issues. The trace may contain file paths, source code, and other potentially sensitive information from your project.",
|
"typescript.tsserver.trace": "Enables tracing of messages sent to the TS server. This trace can be used to diagnose TS Server issues. The trace may contain file paths, source code, and other potentially sensitive information from your project.",
|
||||||
|
"typescript.tsserver.enableRegionDiagnostics": "Enables region-based diagnostics in TypeScript. Requires using TypeScript 5.6+ in the workspace.",
|
||||||
"typescript.validate.enable": "Enable/disable TypeScript validation.",
|
"typescript.validate.enable": "Enable/disable TypeScript validation.",
|
||||||
"typescript.format.enable": "Enable/disable default TypeScript formatter.",
|
"typescript.format.enable": "Enable/disable default TypeScript formatter.",
|
||||||
"javascript.format.enable": "Enable/disable default JavaScript formatter.",
|
"javascript.format.enable": "Enable/disable default JavaScript formatter.",
|
||||||
|
|
|
@ -124,6 +124,7 @@ export interface TypeScriptServiceConfiguration {
|
||||||
readonly localNodePath: string | null;
|
readonly localNodePath: string | null;
|
||||||
readonly globalNodePath: string | null;
|
readonly globalNodePath: string | null;
|
||||||
readonly workspaceSymbolsExcludeLibrarySymbols: boolean;
|
readonly workspaceSymbolsExcludeLibrarySymbols: boolean;
|
||||||
|
readonly enableRegionDiagnostics: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function areServiceConfigurationsEqual(a: TypeScriptServiceConfiguration, b: TypeScriptServiceConfiguration): boolean {
|
export function areServiceConfigurationsEqual(a: TypeScriptServiceConfiguration, b: TypeScriptServiceConfiguration): boolean {
|
||||||
|
@ -162,6 +163,7 @@ export abstract class BaseServiceConfigurationProvider implements ServiceConfigu
|
||||||
localNodePath: this.readLocalNodePath(configuration),
|
localNodePath: this.readLocalNodePath(configuration),
|
||||||
globalNodePath: this.readGlobalNodePath(configuration),
|
globalNodePath: this.readGlobalNodePath(configuration),
|
||||||
workspaceSymbolsExcludeLibrarySymbols: this.readWorkspaceSymbolsExcludeLibrarySymbols(configuration),
|
workspaceSymbolsExcludeLibrarySymbols: this.readWorkspaceSymbolsExcludeLibrarySymbols(configuration),
|
||||||
|
enableRegionDiagnostics: this.readEnableRegionDiagnostics(configuration),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,4 +269,8 @@ export abstract class BaseServiceConfigurationProvider implements ServiceConfigu
|
||||||
private readWebTypeAcquisition(configuration: vscode.WorkspaceConfiguration): boolean {
|
private readWebTypeAcquisition(configuration: vscode.WorkspaceConfiguration): boolean {
|
||||||
return configuration.get<boolean>('typescript.tsserver.web.typeAcquisition.enabled', false);
|
return configuration.get<boolean>('typescript.tsserver.web.typeAcquisition.enabled', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readEnableRegionDiagnostics(configuration: vscode.WorkspaceConfiguration): boolean {
|
||||||
|
return configuration.get<boolean>('typescript.tsserver.enableRegionDiagnostics', true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ export const enum DiagnosticKind {
|
||||||
Syntax,
|
Syntax,
|
||||||
Semantic,
|
Semantic,
|
||||||
Suggestion,
|
Suggestion,
|
||||||
|
RegionSemantic,
|
||||||
}
|
}
|
||||||
|
|
||||||
class FileDiagnostics {
|
class FileDiagnostics {
|
||||||
|
@ -48,7 +49,8 @@ class FileDiagnostics {
|
||||||
public updateDiagnostics(
|
public updateDiagnostics(
|
||||||
language: DiagnosticLanguage,
|
language: DiagnosticLanguage,
|
||||||
kind: DiagnosticKind,
|
kind: DiagnosticKind,
|
||||||
diagnostics: ReadonlyArray<vscode.Diagnostic>
|
diagnostics: ReadonlyArray<vscode.Diagnostic>,
|
||||||
|
ranges: ReadonlyArray<vscode.Range> | undefined
|
||||||
): boolean {
|
): boolean {
|
||||||
if (language !== this.language) {
|
if (language !== this.language) {
|
||||||
this._diagnostics.clear();
|
this._diagnostics.clear();
|
||||||
|
@ -61,6 +63,9 @@ class FileDiagnostics {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kind === DiagnosticKind.RegionSemantic) {
|
||||||
|
return this.updateRegionDiagnostics(diagnostics, ranges!);
|
||||||
|
}
|
||||||
this._diagnostics.set(kind, diagnostics);
|
this._diagnostics.set(kind, diagnostics);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +88,23 @@ class FileDiagnostics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ranges The ranges whose diagnostics were updated.
|
||||||
|
*/
|
||||||
|
private updateRegionDiagnostics(
|
||||||
|
diagnostics: ReadonlyArray<vscode.Diagnostic>,
|
||||||
|
ranges: ReadonlyArray<vscode.Range>): boolean {
|
||||||
|
if (!this._diagnostics.get(DiagnosticKind.Semantic)) {
|
||||||
|
this._diagnostics.set(DiagnosticKind.Semantic, diagnostics);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const oldDiagnostics = this._diagnostics.get(DiagnosticKind.Semantic)!;
|
||||||
|
const newDiagnostics = oldDiagnostics.filter(diag => !ranges.some(range => diag.range.intersection(range)));
|
||||||
|
newDiagnostics.push(...diagnostics);
|
||||||
|
this._diagnostics.set(DiagnosticKind.Semantic, newDiagnostics);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private getSuggestionDiagnostics(settings: DiagnosticSettings) {
|
private getSuggestionDiagnostics(settings: DiagnosticSettings) {
|
||||||
const enableSuggestions = settings.getEnableSuggestions(this.language);
|
const enableSuggestions = settings.getEnableSuggestions(this.language);
|
||||||
return this.get(DiagnosticKind.Suggestion).filter(x => {
|
return this.get(DiagnosticKind.Suggestion).filter(x => {
|
||||||
|
@ -284,15 +306,16 @@ export class DiagnosticsManager extends Disposable {
|
||||||
file: vscode.Uri,
|
file: vscode.Uri,
|
||||||
language: DiagnosticLanguage,
|
language: DiagnosticLanguage,
|
||||||
kind: DiagnosticKind,
|
kind: DiagnosticKind,
|
||||||
diagnostics: ReadonlyArray<vscode.Diagnostic>
|
diagnostics: ReadonlyArray<vscode.Diagnostic>,
|
||||||
|
ranges: ReadonlyArray<vscode.Range> | undefined,
|
||||||
): void {
|
): void {
|
||||||
let didUpdate = false;
|
let didUpdate = false;
|
||||||
const entry = this._diagnostics.get(file);
|
const entry = this._diagnostics.get(file);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
didUpdate = entry.updateDiagnostics(language, kind, diagnostics);
|
didUpdate = entry.updateDiagnostics(language, kind, diagnostics, ranges);
|
||||||
} else if (diagnostics.length) {
|
} else if (diagnostics.length) {
|
||||||
const fileDiagnostics = new FileDiagnostics(file, language);
|
const fileDiagnostics = new FileDiagnostics(file, language);
|
||||||
fileDiagnostics.updateDiagnostics(language, kind, diagnostics);
|
fileDiagnostics.updateDiagnostics(language, kind, diagnostics, ranges);
|
||||||
this._diagnostics.set(file, fileDiagnostics);
|
this._diagnostics.set(file, fileDiagnostics);
|
||||||
didUpdate = true;
|
didUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,11 @@ export default class LanguageProvider extends Disposable {
|
||||||
this.client.bufferSyncSupport.requestAllDiagnostics();
|
this.client.bufferSyncSupport.requestAllDiagnostics();
|
||||||
}
|
}
|
||||||
|
|
||||||
public diagnosticsReceived(diagnosticsKind: DiagnosticKind, file: vscode.Uri, diagnostics: (vscode.Diagnostic & { reportUnnecessary: any; reportDeprecated: any })[]): void {
|
public diagnosticsReceived(
|
||||||
|
diagnosticsKind: DiagnosticKind,
|
||||||
|
file: vscode.Uri,
|
||||||
|
diagnostics: (vscode.Diagnostic & { reportUnnecessary: any; reportDeprecated: any })[],
|
||||||
|
ranges: vscode.Range[] | undefined): void {
|
||||||
if (diagnosticsKind !== DiagnosticKind.Syntax && !this.client.hasCapabilityForResource(file, ClientCapability.Semantic)) {
|
if (diagnosticsKind !== DiagnosticKind.Syntax && !this.client.hasCapabilityForResource(file, ClientCapability.Semantic)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +179,7 @@ export default class LanguageProvider extends Disposable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}));
|
}), ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
public configFileDiagnosticsReceived(file: vscode.Uri, diagnostics: vscode.Diagnostic[]): void {
|
public configFileDiagnosticsReceived(file: vscode.Uri, diagnostics: vscode.Diagnostic[]): void {
|
||||||
|
|
|
@ -275,12 +275,12 @@ class SyncedBufferMap extends ResourceMap<SyncedBuffer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
class PendingDiagnostics extends ResourceMap<number> {
|
class PendingDiagnostics extends ResourceMap<number> {
|
||||||
public getOrderedFileSet(): ResourceMap<void> {
|
public getOrderedFileSet(): ResourceMap<void | vscode.Range[]> {
|
||||||
const orderedResources = Array.from(this.entries())
|
const orderedResources = Array.from(this.entries())
|
||||||
.sort((a, b) => a.value - b.value)
|
.sort((a, b) => a.value - b.value)
|
||||||
.map(entry => entry.resource);
|
.map(entry => entry.resource);
|
||||||
|
|
||||||
const map = new ResourceMap<void>(this._normalizePath, this.config);
|
const map = new ResourceMap<void | vscode.Range[]>(this._normalizePath, this.config);
|
||||||
for (const resource of orderedResources) {
|
for (const resource of orderedResources) {
|
||||||
map.set(resource, undefined);
|
map.set(resource, undefined);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +292,7 @@ class GetErrRequest {
|
||||||
|
|
||||||
public static executeGetErrRequest(
|
public static executeGetErrRequest(
|
||||||
client: ITypeScriptServiceClient,
|
client: ITypeScriptServiceClient,
|
||||||
files: ResourceMap<void>,
|
files: ResourceMap<void | vscode.Range[]>,
|
||||||
onDone: () => void
|
onDone: () => void
|
||||||
) {
|
) {
|
||||||
return new GetErrRequest(client, files, onDone);
|
return new GetErrRequest(client, files, onDone);
|
||||||
|
@ -303,7 +303,7 @@ class GetErrRequest {
|
||||||
|
|
||||||
private constructor(
|
private constructor(
|
||||||
private readonly client: ITypeScriptServiceClient,
|
private readonly client: ITypeScriptServiceClient,
|
||||||
public readonly files: ResourceMap<void>,
|
public readonly files: ResourceMap<void | vscode.Range[]>,
|
||||||
onDone: () => void
|
onDone: () => void
|
||||||
) {
|
) {
|
||||||
if (!this.isErrorReportingEnabled()) {
|
if (!this.isErrorReportingEnabled()) {
|
||||||
|
@ -313,19 +313,39 @@ class GetErrRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
const supportsSyntaxGetErr = this.client.apiVersion.gte(API.v440);
|
const supportsSyntaxGetErr = this.client.apiVersion.gte(API.v440);
|
||||||
const allFiles = coalesce(Array.from(files.entries())
|
const fileEntries = Array.from(files.entries()).filter(entry => supportsSyntaxGetErr || client.hasCapabilityForResource(entry.resource, ClientCapability.Semantic));
|
||||||
.filter(entry => supportsSyntaxGetErr || client.hasCapabilityForResource(entry.resource, ClientCapability.Semantic))
|
const allFiles = coalesce(fileEntries
|
||||||
.map(entry => client.toTsFilePath(entry.resource)));
|
.map(entry => client.toTsFilePath(entry.resource)));
|
||||||
|
|
||||||
if (!allFiles.length) {
|
if (!allFiles.length) {
|
||||||
this._done = true;
|
this._done = true;
|
||||||
setImmediate(onDone);
|
setImmediate(onDone);
|
||||||
} else {
|
} else {
|
||||||
const request = this.areProjectDiagnosticsEnabled()
|
let request;
|
||||||
|
if (this.areProjectDiagnosticsEnabled()) {
|
||||||
// Note that geterrForProject is almost certainly not the api we want here as it ends up computing far
|
// Note that geterrForProject is almost certainly not the api we want here as it ends up computing far
|
||||||
// too many diagnostics
|
// too many diagnostics
|
||||||
? client.executeAsync('geterrForProject', { delay: 0, file: allFiles[0] }, this._token.token)
|
request = client.executeAsync('geterrForProject', { delay: 0, file: allFiles[0] }, this._token.token);
|
||||||
: client.executeAsync('geterr', { delay: 0, files: allFiles }, this._token.token);
|
}
|
||||||
|
else {
|
||||||
|
let requestFiles;
|
||||||
|
if (this.areRegionDiagnosticsEnabled()) {
|
||||||
|
requestFiles = coalesce(fileEntries
|
||||||
|
.map(entry => {
|
||||||
|
const file = client.toTsFilePath(entry.resource);
|
||||||
|
const ranges = entry.value;
|
||||||
|
if (file && ranges) {
|
||||||
|
return typeConverters.Range.toFileRangesRequestArgs(file, ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
requestFiles = allFiles;
|
||||||
|
}
|
||||||
|
request = client.executeAsync('geterr', { delay: 0, files: requestFiles }, this._token.token);
|
||||||
|
}
|
||||||
|
|
||||||
request.finally(() => {
|
request.finally(() => {
|
||||||
if (this._done) {
|
if (this._done) {
|
||||||
|
@ -350,6 +370,10 @@ class GetErrRequest {
|
||||||
return this.client.configuration.enableProjectDiagnostics && this.client.capabilities.has(ClientCapability.Semantic);
|
return this.client.configuration.enableProjectDiagnostics && this.client.capabilities.has(ClientCapability.Semantic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private areRegionDiagnosticsEnabled() {
|
||||||
|
return this.client.configuration.enableRegionDiagnostics && this.client.apiVersion.gte(API.v560);
|
||||||
|
}
|
||||||
|
|
||||||
public cancel(): any {
|
public cancel(): any {
|
||||||
if (!this._done) {
|
if (!this._done) {
|
||||||
this._token.cancel();
|
this._token.cancel();
|
||||||
|
@ -722,7 +746,9 @@ export default class BufferSyncSupport extends Disposable {
|
||||||
|
|
||||||
// Add all open TS buffers to the geterr request. They might be visible
|
// Add all open TS buffers to the geterr request. They might be visible
|
||||||
for (const buffer of this.syncedBuffers.values()) {
|
for (const buffer of this.syncedBuffers.values()) {
|
||||||
orderedFileSet.set(buffer.resource, undefined);
|
const editors = vscode.window.visibleTextEditors.filter(editor => editor.document.uri.toString() === buffer.resource.toString());
|
||||||
|
const visibleRanges = editors.flatMap(editor => editor.visibleRanges);
|
||||||
|
orderedFileSet.set(buffer.resource, visibleRanges.length ? visibleRanges : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const { resource } of orderedFileSet.entries()) {
|
for (const { resource } of orderedFileSet.entries()) {
|
||||||
|
|
|
@ -78,6 +78,7 @@ export enum EventName {
|
||||||
syntaxDiag = 'syntaxDiag',
|
syntaxDiag = 'syntaxDiag',
|
||||||
semanticDiag = 'semanticDiag',
|
semanticDiag = 'semanticDiag',
|
||||||
suggestionDiag = 'suggestionDiag',
|
suggestionDiag = 'suggestionDiag',
|
||||||
|
regionSemanticDiag = 'regionSemanticDiag',
|
||||||
configFileDiag = 'configFileDiag',
|
configFileDiag = 'configFileDiag',
|
||||||
telemetry = 'telemetry',
|
telemetry = 'telemetry',
|
||||||
projectLanguageServiceState = 'projectLanguageServiceState',
|
projectLanguageServiceState = 'projectLanguageServiceState',
|
||||||
|
|
|
@ -26,14 +26,24 @@ export namespace Range {
|
||||||
Math.max(0, start.line - 1), Math.max(start.offset - 1, 0),
|
Math.max(0, start.line - 1), Math.max(start.offset - 1, 0),
|
||||||
Math.max(0, end.line - 1), Math.max(0, end.offset - 1));
|
Math.max(0, end.line - 1), Math.max(0, end.offset - 1));
|
||||||
|
|
||||||
export const toFileRangeRequestArgs = (file: string, range: vscode.Range): Proto.FileRangeRequestArgs => ({
|
// @ts-expect-error until ts 5.6
|
||||||
file,
|
export const toFileRange = (range: vscode.Range): Proto.FileRange => ({
|
||||||
startLine: range.start.line + 1,
|
startLine: range.start.line + 1,
|
||||||
startOffset: range.start.character + 1,
|
startOffset: range.start.character + 1,
|
||||||
endLine: range.end.line + 1,
|
endLine: range.end.line + 1,
|
||||||
endOffset: range.end.character + 1
|
endOffset: range.end.character + 1
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const toFileRangeRequestArgs = (file: string, range: vscode.Range): Proto.FileRangeRequestArgs => ({
|
||||||
|
file,
|
||||||
|
...toFileRange(range)
|
||||||
|
});
|
||||||
|
// @ts-expect-error until ts 5.6
|
||||||
|
export const toFileRangesRequestArgs = (file: string, ranges: vscode.Range[]): Proto.FileRangesRequestArgs => ({
|
||||||
|
file,
|
||||||
|
ranges: ranges.map(toFileRange)
|
||||||
|
});
|
||||||
|
|
||||||
export const toFormattingRequestArgs = (file: string, range: vscode.Range): Proto.FormatRequestArgs => ({
|
export const toFormattingRequestArgs = (file: string, range: vscode.Range): Proto.FormatRequestArgs => ({
|
||||||
file,
|
file,
|
||||||
line: range.start.line + 1,
|
line: range.start.line + 1,
|
||||||
|
|
|
@ -90,8 +90,8 @@ export default class TypeScriptServiceClientHost extends Disposable {
|
||||||
services,
|
services,
|
||||||
allModeIds));
|
allModeIds));
|
||||||
|
|
||||||
this.client.onDiagnosticsReceived(({ kind, resource, diagnostics }) => {
|
this.client.onDiagnosticsReceived(({ kind, resource, diagnostics, spans }) => {
|
||||||
this.diagnosticsReceived(kind, resource, diagnostics);
|
this.diagnosticsReceived(kind, resource, diagnostics, spans);
|
||||||
}, null, this._disposables);
|
}, null, this._disposables);
|
||||||
|
|
||||||
this.client.onConfigDiagnosticsReceived(diag => this.configFileDiagnosticsReceived(diag), null, this._disposables);
|
this.client.onConfigDiagnosticsReceived(diag => this.configFileDiagnosticsReceived(diag), null, this._disposables);
|
||||||
|
@ -236,14 +236,16 @@ export default class TypeScriptServiceClientHost extends Disposable {
|
||||||
private async diagnosticsReceived(
|
private async diagnosticsReceived(
|
||||||
kind: DiagnosticKind,
|
kind: DiagnosticKind,
|
||||||
resource: vscode.Uri,
|
resource: vscode.Uri,
|
||||||
diagnostics: Proto.Diagnostic[]
|
diagnostics: Proto.Diagnostic[],
|
||||||
|
spans: Proto.TextSpan[] | undefined,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const language = await this.findLanguage(resource);
|
const language = await this.findLanguage(resource);
|
||||||
if (language) {
|
if (language) {
|
||||||
language.diagnosticsReceived(
|
language.diagnosticsReceived(
|
||||||
kind,
|
kind,
|
||||||
resource,
|
resource,
|
||||||
this.createMarkerDatas(diagnostics, language.diagnosticSource));
|
this.createMarkerDatas(diagnostics, language.diagnosticSource),
|
||||||
|
spans?.map(span => typeConverters.Range.fromTextSpan(span)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ export interface TsDiagnostics {
|
||||||
readonly kind: DiagnosticKind;
|
readonly kind: DiagnosticKind;
|
||||||
readonly resource: vscode.Uri;
|
readonly resource: vscode.Uri;
|
||||||
readonly diagnostics: Proto.Diagnostic[];
|
readonly diagnostics: Proto.Diagnostic[];
|
||||||
|
readonly spans?: Proto.TextSpan[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ToCancelOnResourceChanged {
|
interface ToCancelOnResourceChanged {
|
||||||
|
@ -947,7 +948,8 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||||
switch (event.event) {
|
switch (event.event) {
|
||||||
case EventName.syntaxDiag:
|
case EventName.syntaxDiag:
|
||||||
case EventName.semanticDiag:
|
case EventName.semanticDiag:
|
||||||
case EventName.suggestionDiag: {
|
case EventName.suggestionDiag:
|
||||||
|
case EventName.regionSemanticDiag: {
|
||||||
// This event also roughly signals that projects have been loaded successfully (since the TS server is synchronous)
|
// This event also roughly signals that projects have been loaded successfully (since the TS server is synchronous)
|
||||||
this.loadingIndicator.reset();
|
this.loadingIndicator.reset();
|
||||||
|
|
||||||
|
@ -956,7 +958,9 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||||
this._onDiagnosticsReceived.fire({
|
this._onDiagnosticsReceived.fire({
|
||||||
kind: getDiagnosticsKind(event),
|
kind: getDiagnosticsKind(event),
|
||||||
resource: this.toResource(diagnosticEvent.body.file),
|
resource: this.toResource(diagnosticEvent.body.file),
|
||||||
diagnostics: diagnosticEvent.body.diagnostics
|
diagnostics: diagnosticEvent.body.diagnostics,
|
||||||
|
// @ts-expect-error until ts 5.6
|
||||||
|
spans: diagnosticEvent.body.spans,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1261,6 +1265,7 @@ function getDiagnosticsKind(event: Proto.Event) {
|
||||||
case 'syntaxDiag': return DiagnosticKind.Syntax;
|
case 'syntaxDiag': return DiagnosticKind.Syntax;
|
||||||
case 'semanticDiag': return DiagnosticKind.Semantic;
|
case 'semanticDiag': return DiagnosticKind.Semantic;
|
||||||
case 'suggestionDiag': return DiagnosticKind.Suggestion;
|
case 'suggestionDiag': return DiagnosticKind.Suggestion;
|
||||||
|
case 'regionSemanticDiag': return DiagnosticKind.RegionSemantic;
|
||||||
}
|
}
|
||||||
throw new Error('Unknown dignostics kind');
|
throw new Error('Unknown dignostics kind');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue