pss-langserver
Version:
A Language server for the Portable Stimulus Standard
105 lines (104 loc) • 4.79 kB
JavaScript
;
/*
* Copyright (C) 2025 Darshan(@thisisthedarshan)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getGoToDefinition = getGoToDefinition;
exports.getGoToDefinitionAdvanced = getGoToDefinitionAdvanced;
exports.getGoToDeclarationsAdvanced = getGoToDeclarationsAdvanced;
exports.getReferencesAdvanced = getReferencesAdvanced;
exports.wordAt = wordAt;
const node_1 = require("vscode-languageserver/node");
const dataTypes_1 = require("../definitions/dataTypes");
const helpers_1 = require("../parser/helpers");
function getGoToDefinition(document, pos, ast) {
const keyword = wordAt(document, pos);
let location = null;
if (keyword === null) {
return null;
}
/* Iterate through each metaData object in the array */
for (const metaInfoObj of ast) {
/* Check if the searchString matches any key in the current metaData object */
const matchingKey = Object.keys(metaInfoObj).find(key => key === keyword);
/* If a match is found, return the location */
if (matchingKey) {
const info = metaInfoObj[matchingKey];
/* Subtracting 1 from line number since Antlr starts line number from 1 and we expect from 0 */
let start_range = node_1.Position.create(info.onLine.lineNumber - 1, info.onLine.columnNumber);
let end_range = node_1.Position.create(info.onLine.lineNumber - 1, info.onLine.columnNumber + keyword.length);
location = node_1.Location.create(info.onLine.file, node_1.Range.create(start_range, end_range));
return location;
}
}
return location;
}
function getGoToDefinitionAdvanced(document, pos, ast) {
const keyword = wordAt(document, pos);
let location = null;
if (keyword === null) {
return null;
}
const node = (0, helpers_1.getNodeFromNameArray)(ast, keyword, dataTypes_1.objType.ASSIGNMENT);
if (node) {
if (node.definedOn) {
let start_range = node_1.Position.create(node.definedOn.lineNumber - 1, node.definedOn.columnNumber);
let end_range = node_1.Position.create(node.definedOn.lineNumber - 1, node.definedOn.columnNumber + keyword.length);
location = node_1.Location.create(node.definedOn.file, node_1.Range.create(start_range, end_range));
}
}
return location;
}
function getGoToDeclarationsAdvanced(document, pos, ast) {
let definitions = [];
const keyword = wordAt(document, pos);
if (keyword === null) {
return null;
}
const items = (0, helpers_1.collectAllPSSNodes)(ast, { name: keyword });
items.forEach(node => {
let start_range = node_1.Position.create(node.definedOn.lineNumber - 1, node.definedOn.columnNumber);
let end_range = node_1.Position.create(node.definedOn.lineNumber - 1, node.definedOn.columnNumber + keyword.length);
definitions.push(node_1.Location.create(node.definedOn.file, node_1.Range.create(start_range, end_range)));
});
return definitions.length > 0 ? definitions : null;
}
function getReferencesAdvanced(document, pos, ast) {
let references = [];
const keyword = wordAt(document, pos);
if (keyword === null) {
return undefined;
}
const items = (0, helpers_1.collectAllPSSNodes)(ast, { name: keyword }, { skipType: dataTypes_1.objType.INSTANCE });
items.forEach(node => {
let start_range = node_1.Position.create(node.definedOn.lineNumber - 1, node.definedOn.columnNumber);
let end_range = node_1.Position.create(node.definedOn.lineNumber - 1, node.definedOn.columnNumber + keyword.length);
references.push(node_1.Location.create(node.definedOn.file, node_1.Range.create(start_range, end_range)));
});
return references;
}
function wordAt(text, offset) {
const wordRegex = /\b[a-zA-Z_][a-zA-Z0-9_]*\b/g;
let match;
while ((match = wordRegex.exec(text))) {
const start = match.index;
const end = start + match[0].length;
if (offset >= start && offset <= end) {
return match[0]; // Return the matched word
}
}
return null;
}