@eclipse-glsp/theia-integration
Version:
Glue code to integrate GLSP clients into Eclipse Theia
215 lines • 9.35 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TheiaMarkerManager = exports.TheiaMarkerManagerFactory = void 0;
exports.connectTheiaMarkerManager = connectTheiaMarkerManager;
/********************************************************************************
* Copyright (c) 2020-2026 EclipseSource and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
const lib_1 = require("@eclipse-glsp/client/lib");
const core_1 = require("@theia/core");
const inversify_1 = require("@theia/core/shared/inversify");
const problem_manager_1 = require("@theia/markers/lib/browser/problem/problem-manager");
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
const browser_1 = require("@theia/core/lib/browser");
const theia_opener_options_navigation_service_1 = require("../theia-opener-options-navigation-service");
const glsp_diagram_widget_1 = require("./glsp-diagram-widget");
exports.TheiaMarkerManagerFactory = Symbol('TheiaMarkerManagerFactory');
function connectTheiaMarkerManager(container, markerManagerFactory, languageLabel) {
const markerManager = markerManagerFactory();
if (markerManager instanceof lib_1.ExternalMarkerManager) {
(0, lib_1.bindOrRebind)(container, lib_1.ExternalMarkerManager).toConstantValue(markerManager);
markerManager.languageLabel = languageLabel;
markerManager.connect(container.get(lib_1.TYPES.IActionDispatcher));
}
}
class DiagnosticMarkers {
constructor() {
this.diagnostic2marker = new Map();
}
get size() {
return this.diagnostic2marker.size;
}
all() {
return this.diagnostic2marker.values();
}
marker(diagnostic) {
return this.diagnostic2marker.get(diagnostic);
}
add(diagnostic, marker) {
return this.diagnostic2marker.set(diagnostic, marker);
}
getMarkerByOrigin(origin) {
return Array.from(this.diagnostic2marker.values()).filter(marker => marker.reason === origin);
}
getByOrigin(origin) {
const diagnostics = [];
this.diagnostic2marker.forEach((marker, diagnostic) => {
if (marker.reason === origin) {
diagnostics.push(diagnostic);
}
});
return diagnostics;
}
deleteByOrigin(origin) {
const toDelete = [];
this.diagnostic2marker.forEach((marker, diagnostic) => {
if (marker.reason === origin) {
toDelete.push(diagnostic);
}
});
toDelete.forEach(diagnostic => this.delete(diagnostic));
}
delete(diagnostic) {
return this.diagnostic2marker.delete(diagnostic);
}
clear() {
return this.diagnostic2marker.clear();
}
}
let TheiaMarkerManager = class TheiaMarkerManager extends lib_1.ExternalMarkerManager {
constructor() {
super(...arguments);
this.markerReasonsToKeep = [lib_1.MarkersReason.LIVE];
this.uri2markers = new Map();
this.toDispose = new core_1.DisposableCollection();
}
markers(uri) {
const markers = this.uri2markers.get(uri.toString());
if (markers === undefined) {
const newMarker = new DiagnosticMarkers();
this.uri2markers.set(uri.toString(), newMarker);
return newMarker;
}
return markers;
}
initialize() {
if (this.problemManager) {
this.toDispose.push(this.problemManager.onDidChangeMarkers(uri => this.refreshMarker(uri)));
}
if (this.shell) {
this.toDispose.push(this.shell.onDidRemoveWidget(widget => this.handleWidgetClose(widget)));
}
}
async refreshMarker(uri) {
if (this.problemManager === undefined || this.markers(uri).size < 1) {
return;
}
const toDelete = [...this.markers(uri).all()];
for (const existingMarker of this.problemManager.findMarkers({ uri })) {
const diagnostic = existingMarker.data;
const marker = this.markers(uri).marker(diagnostic);
if (marker) {
const index = toDelete.indexOf(marker);
if (index > -1) {
toDelete.splice(index, 1);
}
else {
this.markers(uri).delete(diagnostic);
}
}
}
if (toDelete.length > 0) {
this.removeMarkers(toDelete);
}
}
setMarkers(markers, reason, sourceUri) {
if (this.problemManager === undefined) {
return;
}
const uri = new core_1.URI(sourceUri);
this.markers(uri).deleteByOrigin(reason);
const existingOtherMarkers = [...this.markers(uri).all()];
this.markers(uri).clear();
const existingOtherDiagnostics = existingOtherMarkers.map(marker => this.createDiagnostic(uri, marker, marker.reason));
const newDiagnostics = markers.map(marker => this.createDiagnostic(uri, marker, reason));
this.problemManager.setMarkers(uri, this.languageLabel, [...existingOtherDiagnostics, ...newDiagnostics]);
}
createDiagnostic(uri, marker, origin) {
const range = theia_opener_options_navigation_service_1.SelectionWithElementIds.createRange([marker.elementId]);
const diagnostic = vscode_languageserver_types_1.Diagnostic.create(range, marker.label, this.toSeverity(marker.kind));
this.markers(uri).add(diagnostic, { ...marker, reason: origin });
return diagnostic;
}
toSeverity(kind) {
switch (kind) {
case lib_1.MarkerKind.ERROR:
return 1;
case lib_1.MarkerKind.WARNING:
return 2;
case lib_1.MarkerKind.INFO:
return 3;
default:
return undefined;
}
}
dispose() {
this.toDispose.dispose();
this.actionDispatcher = undefined;
}
handleWidgetClose(widget) {
var _a;
const resourceUri = (_a = (0, glsp_diagram_widget_1.getDiagramWidget)(widget)) === null || _a === void 0 ? void 0 : _a.getResourceUri();
if (resourceUri) {
this.clearMarkers(resourceUri, this.markerReasonsToKeep);
}
}
clearMarkers(uri, exceptThoseWithReasons) {
var _a;
const diagnostics = [];
for (const reason of exceptThoseWithReasons) {
const markersToKeep = this.markers(uri).getMarkerByOrigin(reason);
this.markers(uri).clear();
const diagnosticsToKeep = markersToKeep.map(marker => this.createDiagnostic(uri, marker, reason));
diagnostics.push(...diagnosticsToKeep);
}
(_a = this.problemManager) === null || _a === void 0 ? void 0 : _a.setMarkers(uri, this.languageLabel, diagnostics);
}
};
exports.TheiaMarkerManager = TheiaMarkerManager;
__decorate([
(0, inversify_1.inject)(problem_manager_1.ProblemManager),
(0, inversify_1.optional)(),
__metadata("design:type", problem_manager_1.ProblemManager)
], TheiaMarkerManager.prototype, "problemManager", void 0);
__decorate([
(0, inversify_1.inject)(browser_1.ApplicationShell),
(0, inversify_1.optional)(),
__metadata("design:type", browser_1.ApplicationShell)
], TheiaMarkerManager.prototype, "shell", void 0);
__decorate([
(0, inversify_1.postConstruct)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], TheiaMarkerManager.prototype, "initialize", null);
__decorate([
(0, inversify_1.preDestroy)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], TheiaMarkerManager.prototype, "dispose", null);
exports.TheiaMarkerManager = TheiaMarkerManager = __decorate([
(0, inversify_1.injectable)()
], TheiaMarkerManager);
//# sourceMappingURL=theia-marker-manager.js.map