Skip to content

Commit

Permalink
Move VS Code language service modules into their own folder (#2055)
Browse files Browse the repository at this point in the history
With the new feature I'm planning to add to VS Code extension, I needed
to organize this folder a bit before I proceed. It was getting out of
hand.

This PR moves everything language-service related into its own folder
under `vscode/src`.

The only slight, expected, behavior change here is in the initialization
order of diagnostics (which had to happen as a result of me separating
out the different kinds of diagnostics.) I don't think it should have
any observable effect.
  • Loading branch information
minestarks authored Dec 9, 2024
1 parent f026774 commit 5a86a67
Show file tree
Hide file tree
Showing 16 changed files with 558 additions and 535 deletions.
39 changes: 38 additions & 1 deletion vscode/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { TextDocument, Uri, Range, Location } from "vscode";
import { Utils } from "vscode-uri";
import { ILocation, IRange, IWorkspaceEdit } from "qsharp-lang";
import { ILocation, IRange, IWorkspaceEdit, VSDiagnostic } from "qsharp-lang";
import * as vscode from "vscode";

export const qsharpLanguageId = "qsharp";
Expand Down Expand Up @@ -58,3 +58,40 @@ export function toVscodeWorkspaceEdit(
}
return workspaceEdit;
}

export function toVsCodeDiagnostic(d: VSDiagnostic): vscode.Diagnostic {
let severity;
switch (d.severity) {
case "error":
severity = vscode.DiagnosticSeverity.Error;
break;
case "warning":
severity = vscode.DiagnosticSeverity.Warning;
break;
case "info":
severity = vscode.DiagnosticSeverity.Information;
break;
}
const vscodeDiagnostic = new vscode.Diagnostic(
toVscodeRange(d.range),
d.message,
severity,
);
if (d.uri && d.code) {
vscodeDiagnostic.code = {
value: d.code,
target: vscode.Uri.parse(d.uri),
};
} else if (d.code) {
vscodeDiagnostic.code = d.code;
}
if (d.related) {
vscodeDiagnostic.relatedInformation = d.related.map((r) => {
return new vscode.DiagnosticRelatedInformation(
toVscodeLocation(r.location),
r.message,
);
});
}
return vscodeDiagnostic;
}
104 changes: 12 additions & 92 deletions vscode/src/diagnostics.ts
Original file line number Diff line number Diff line change
@@ -1,100 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import {
ILanguageService,
IQSharpError,
VSDiagnostic,
log,
qsharpLibraryUriScheme,
} from "qsharp-lang";
import { IQSharpError, log, qsharpLibraryUriScheme } from "qsharp-lang";
import * as vscode from "vscode";
import { toVscodeLocation, toVscodeRange, qsharpLanguageId } from "./common.js";
import { qsharpLanguageId, toVsCodeDiagnostic } from "./common.js";

export function startCheckingQSharp(
languageService: ILanguageService,
): vscode.Disposable[] {
return [
...startLanguageServiceDiagnostics(languageService),
...startQsharpJsonDiagnostics(),
...startCommandDiagnostics(),
];
}

function startLanguageServiceDiagnostics(
languageService: ILanguageService,
): vscode.Disposable[] {
const diagCollection =
vscode.languages.createDiagnosticCollection(qsharpLanguageId);

async function onDiagnostics(evt: {
detail: {
uri: string;
version: number;
diagnostics: VSDiagnostic[];
};
}) {
const diagnostics = evt.detail;
const uri = vscode.Uri.parse(diagnostics.uri);

if (uri.scheme === qsharpLibraryUriScheme) {
// Don't report diagnostics for library files.
return;
}

diagCollection.set(
uri,
diagnostics.diagnostics.map((d) => toVsCodeDiagnostic(d)),
);
}

languageService.addEventListener("diagnostics", onDiagnostics);

return [
{
dispose: () => {
languageService.removeEventListener("diagnostics", onDiagnostics);
},
},
diagCollection,
];
}

export function toVsCodeDiagnostic(d: VSDiagnostic): vscode.Diagnostic {
let severity;
switch (d.severity) {
case "error":
severity = vscode.DiagnosticSeverity.Error;
break;
case "warning":
severity = vscode.DiagnosticSeverity.Warning;
break;
case "info":
severity = vscode.DiagnosticSeverity.Information;
break;
}
const vscodeDiagnostic = new vscode.Diagnostic(
toVscodeRange(d.range),
d.message,
severity,
);
if (d.uri && d.code) {
vscodeDiagnostic.code = {
value: d.code,
target: vscode.Uri.parse(d.uri),
};
} else if (d.code) {
vscodeDiagnostic.code = d.code;
}
if (d.related) {
vscodeDiagnostic.relatedInformation = d.related.map((r) => {
return new vscode.DiagnosticRelatedInformation(
toVscodeLocation(r.location),
r.message,
);
});
}
return vscodeDiagnostic;
/**
* Initialize diagnostics for `qsharp.json` files and failures
* that get reported from various Q# commands.
*
* These are distinct from the errors reported by the Q# language
* service, (a.k.a. compiler errors that get reported as you type).
* Those are initialized in `language-service/diagnostics.js`
*/
export function startOtherQSharpDiagnostics(): vscode.Disposable[] {
return [...startQsharpJsonDiagnostics(), ...startCommandDiagnostics()];
}

//
Expand Down
Loading

0 comments on commit 5a86a67

Please sign in to comment.