- Hover provider showing entity information and type - Go-to-definition (F12) for entity references - Basic IFC file validation (ISO-10303-21 header check) - Entity parsing with regex-based detection - Proper CommonJS module system (avoiding ES module issues) This replaces the broken baseline from ifc-developer-tools which had: - Non-functional ES module configuration - Circular dependency issues - Parser crashes - Non-working PositionVisitor Built on Microsoft's LSP example template for a clean, maintainable foundation. Next: Add hierarchical entity dependency tree in hover tooltip."
148 lines
5.9 KiB
JavaScript
148 lines
5.9 KiB
JavaScript
"use strict";
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
* ------------------------------------------------------------------------------------------ */
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.WorkspaceFoldersFeature = exports.arrayDiff = void 0;
|
|
const UUID = require("./utils/uuid");
|
|
const vscode_1 = require("vscode");
|
|
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
|
|
function access(target, key) {
|
|
if (target === undefined || target === null) {
|
|
return undefined;
|
|
}
|
|
return target[key];
|
|
}
|
|
function arrayDiff(left, right) {
|
|
return left.filter(element => right.indexOf(element) < 0);
|
|
}
|
|
exports.arrayDiff = arrayDiff;
|
|
class WorkspaceFoldersFeature {
|
|
constructor(client) {
|
|
this._client = client;
|
|
this._listeners = new Map();
|
|
}
|
|
getState() {
|
|
return { kind: 'workspace', id: this.registrationType.method, registrations: this._listeners.size > 0 };
|
|
}
|
|
get registrationType() {
|
|
return vscode_languageserver_protocol_1.DidChangeWorkspaceFoldersNotification.type;
|
|
}
|
|
fillInitializeParams(params) {
|
|
const folders = vscode_1.workspace.workspaceFolders;
|
|
this.initializeWithFolders(folders);
|
|
if (folders === void 0) {
|
|
params.workspaceFolders = null;
|
|
}
|
|
else {
|
|
params.workspaceFolders = folders.map(folder => this.asProtocol(folder));
|
|
}
|
|
}
|
|
initializeWithFolders(currentWorkspaceFolders) {
|
|
this._initialFolders = currentWorkspaceFolders;
|
|
}
|
|
fillClientCapabilities(capabilities) {
|
|
capabilities.workspace = capabilities.workspace || {};
|
|
capabilities.workspace.workspaceFolders = true;
|
|
}
|
|
initialize(capabilities) {
|
|
const client = this._client;
|
|
client.onRequest(vscode_languageserver_protocol_1.WorkspaceFoldersRequest.type, (token) => {
|
|
const workspaceFolders = () => {
|
|
const folders = vscode_1.workspace.workspaceFolders;
|
|
if (folders === undefined) {
|
|
return null;
|
|
}
|
|
const result = folders.map((folder) => {
|
|
return this.asProtocol(folder);
|
|
});
|
|
return result;
|
|
};
|
|
const middleware = client.middleware.workspace;
|
|
return middleware && middleware.workspaceFolders
|
|
? middleware.workspaceFolders(token, workspaceFolders)
|
|
: workspaceFolders(token);
|
|
});
|
|
const value = access(access(access(capabilities, 'workspace'), 'workspaceFolders'), 'changeNotifications');
|
|
let id;
|
|
if (typeof value === 'string') {
|
|
id = value;
|
|
}
|
|
else if (value === true) {
|
|
id = UUID.generateUuid();
|
|
}
|
|
if (id) {
|
|
this.register({ id: id, registerOptions: undefined });
|
|
}
|
|
}
|
|
sendInitialEvent(currentWorkspaceFolders) {
|
|
let promise;
|
|
if (this._initialFolders && currentWorkspaceFolders) {
|
|
const removed = arrayDiff(this._initialFolders, currentWorkspaceFolders);
|
|
const added = arrayDiff(currentWorkspaceFolders, this._initialFolders);
|
|
if (added.length > 0 || removed.length > 0) {
|
|
promise = this.doSendEvent(added, removed);
|
|
}
|
|
}
|
|
else if (this._initialFolders) {
|
|
promise = this.doSendEvent([], this._initialFolders);
|
|
}
|
|
else if (currentWorkspaceFolders) {
|
|
promise = this.doSendEvent(currentWorkspaceFolders, []);
|
|
}
|
|
if (promise !== undefined) {
|
|
promise.catch((error) => {
|
|
this._client.error(`Sending notification ${vscode_languageserver_protocol_1.DidChangeWorkspaceFoldersNotification.type.method} failed`, error);
|
|
});
|
|
}
|
|
}
|
|
doSendEvent(addedFolders, removedFolders) {
|
|
let params = {
|
|
event: {
|
|
added: addedFolders.map(folder => this.asProtocol(folder)),
|
|
removed: removedFolders.map(folder => this.asProtocol(folder))
|
|
}
|
|
};
|
|
return this._client.sendNotification(vscode_languageserver_protocol_1.DidChangeWorkspaceFoldersNotification.type, params);
|
|
}
|
|
register(data) {
|
|
let id = data.id;
|
|
let client = this._client;
|
|
let disposable = vscode_1.workspace.onDidChangeWorkspaceFolders((event) => {
|
|
let didChangeWorkspaceFolders = (event) => {
|
|
return this.doSendEvent(event.added, event.removed);
|
|
};
|
|
let middleware = client.middleware.workspace;
|
|
const promise = middleware && middleware.didChangeWorkspaceFolders
|
|
? middleware.didChangeWorkspaceFolders(event, didChangeWorkspaceFolders)
|
|
: didChangeWorkspaceFolders(event);
|
|
promise.catch((error) => {
|
|
this._client.error(`Sending notification ${vscode_languageserver_protocol_1.DidChangeWorkspaceFoldersNotification.type.method} failed`, error);
|
|
});
|
|
});
|
|
this._listeners.set(id, disposable);
|
|
this.sendInitialEvent(vscode_1.workspace.workspaceFolders);
|
|
}
|
|
unregister(id) {
|
|
let disposable = this._listeners.get(id);
|
|
if (disposable === void 0) {
|
|
return;
|
|
}
|
|
this._listeners.delete(id);
|
|
disposable.dispose();
|
|
}
|
|
clear() {
|
|
for (let disposable of this._listeners.values()) {
|
|
disposable.dispose();
|
|
}
|
|
this._listeners.clear();
|
|
}
|
|
asProtocol(workspaceFolder) {
|
|
if (workspaceFolder === void 0) {
|
|
return null;
|
|
}
|
|
return { uri: this._client.code2ProtocolConverter.asUri(workspaceFolder.uri), name: workspaceFolder.name };
|
|
}
|
|
}
|
|
exports.WorkspaceFoldersFeature = WorkspaceFoldersFeature;
|