@imc-trading/svlangserver
Version:
A language server for systemverilog
236 lines (235 loc) • 9.25 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SystemVerilogSymbol = void 0;
const node_1 = require("vscode-languageserver/node");
const genutils_1 = require("./genutils");
class SystemVerilogSymbol {
constructor(name, defLocations, symLocation, containers, type) {
this.name = name;
this.defLocations = defLocations;
this.symLocation = symLocation;
this.containers = containers;
this.type = type;
}
static _toRangeJSON(range) {
return [[range.start.line, range.start.character], [range.end.line, range.end.character]];
}
static _isRangeJSON(rangeJSON) {
return (Array.isArray(rangeJSON[0])) && (typeof rangeJSON[0][0] === "number");
}
static _toRange(rangeJSON) {
return node_1.Range.create(rangeJSON[0][0], rangeJSON[0][1], rangeJSON[1][0], rangeJSON[1][1]);
}
static _defLocationsToJSON(defLocations) {
let defLocationsJSON;
if (Array.isArray(defLocations)) {
defLocationsJSON = [];
for (let defLocation of defLocations) {
if (typeof defLocation === "string") {
defLocationsJSON.push(defLocation);
}
else {
defLocationsJSON.push(SystemVerilogSymbol._toRangeJSON(defLocation));
}
}
}
else {
defLocationsJSON = SystemVerilogSymbol._toRangeJSON(defLocations);
}
return defLocationsJSON;
}
static _symLocationToJSON(symLocation) {
let symLocationJSON;
if (typeof symLocation === "number") {
symLocationJSON = symLocation;
}
else if (Array.isArray(symLocation)) {
symLocationJSON = [symLocation[0], SystemVerilogSymbol._toRangeJSON(symLocation[1])];
}
else {
symLocationJSON = SystemVerilogSymbol._toRangeJSON(symLocation);
}
return symLocationJSON;
}
toJSON() {
try {
return [
this.name,
SystemVerilogSymbol._defLocationsToJSON(this.defLocations),
SystemVerilogSymbol._symLocationToJSON(this.symLocation),
this.containers,
this.type
];
}
catch (error) {
genutils_1.ConnectionLogger.error(error);
return [
this.name,
[[undefined, undefined], [undefined, undefined]],
[[undefined, undefined], [undefined, undefined]],
this.containers,
this.type
];
}
}
static fromJSON(uri, jsonSymbol) {
try {
let defLocations;
if (SystemVerilogSymbol._isRangeJSON(jsonSymbol[1])) {
defLocations = SystemVerilogSymbol._toRange((jsonSymbol[1]));
}
else {
defLocations = [];
for (let defLocationJSON of jsonSymbol[1]) {
if (typeof defLocationJSON === "string") {
defLocations.push(defLocationJSON);
}
else {
defLocations.push(SystemVerilogSymbol._toRange((defLocationJSON)));
}
}
}
let symLocation;
if (typeof jsonSymbol[2] === "number") {
symLocation = jsonSymbol[2];
}
else if (SystemVerilogSymbol._isRangeJSON(jsonSymbol[2])) {
symLocation = SystemVerilogSymbol._toRange((jsonSymbol[2]));
}
else {
symLocation = [(jsonSymbol[2][0]), SystemVerilogSymbol._toRange((jsonSymbol[2][1]))];
}
return new SystemVerilogSymbol(jsonSymbol[0], defLocations, symLocation, jsonSymbol[3], jsonSymbol[4]);
}
catch (error) {
genutils_1.ConnectionLogger.error(error);
return undefined;
}
}
getSymbolLocation(uri) {
try {
let symRange;
let symURI = uri;
if (typeof this.symLocation === "number") {
if (!Array.isArray(this.defLocations)) {
genutils_1.ConnectionLogger.error(`Invalid symbol location (number) when defLocations is not an array`);
}
let l = 0;
for (let i = 0; i < (this.defLocations).length; i++) {
if (typeof this.defLocations[i] === "string") {
symURI = this.defLocations[i];
}
else if (l == this.symLocation) {
symRange = this.defLocations[i];
break;
}
else {
l++;
}
}
}
else if (Array.isArray(this.symLocation)) {
symURI = this.symLocation[0];
symRange = this.symLocation[1];
}
else {
symRange = this.symLocation;
}
return node_1.Location.create(symURI, symRange);
}
catch (error) {
genutils_1.ConnectionLogger.error(error);
return undefined;
}
}
toSymbolInformation(uri) {
try {
let symLocation = this.getSymbolLocation(uri);
return node_1.SymbolInformation.create(this.name, getSymbolKind(this.type), symLocation.range, symLocation.uri, this.containers.length > 0 ? this.containers[this.containers.length - 1] : undefined);
}
catch (error) {
genutils_1.ConnectionLogger.error(error);
return undefined;
}
}
overwrite(symbol) {
this.name = symbol.name;
this.defLocations = symbol.defLocations;
this.symLocation = symbol.symLocation;
this.containers = symbol.containers;
this.type = symbol.type;
}
getDefinition(uri) {
return SystemVerilogSymbol.getDefinitions(uri, [this])[0];
}
static getDefinitions(uri, symbols) {
try {
let documentMap = new Map();
let currDocument;
let definitions = [];
for (let symbol of symbols) {
let defLocations = Array.isArray(symbol.defLocations) ? [uri].concat((symbol.defLocations)) : [uri, (symbol.defLocations)];
let definition = "";
for (let i = 0; i < defLocations.length; i++) {
if (typeof defLocations[i] === "string") {
if (documentMap.has((defLocations[i]))) {
currDocument = documentMap.get((defLocations[i]));
}
else {
let data = genutils_1.fsReadFileSync(genutils_1.uriToPath((defLocations[i])));
currDocument = node_1.TextDocument.create((defLocations[i]), "SystemVerilog", 0, data.toString());
documentMap.set((defLocations[i]), currDocument);
}
}
else {
definition = definition.concat(currDocument.getText((defLocations[i])));
}
}
definitions.push(definition);
}
return definitions;
}
catch (error) {
genutils_1.ConnectionLogger.error(error);
return [];
}
}
getSymbolDocumentPath(uri) {
if (Array.isArray(this.defLocations) && (typeof this.defLocations[0] === "string")) {
return this.defLocations[0];
}
return uri;
}
}
exports.SystemVerilogSymbol = SystemVerilogSymbol;
function getSymbolKind(name) {
if ((name === undefined) ||
(name.length <= 0) ||
(name[0] === '')) {
return node_1.SymbolKind.Variable;
}
switch (name[0]) {
case 'macro': return node_1.SymbolKind.Method;
case 'parameter-port': return node_1.SymbolKind.Property;
case 'port': return node_1.SymbolKind.Variable;
case 'module': return node_1.SymbolKind.Class;
case 'macromodule': return node_1.SymbolKind.Class;
case 'interface': return node_1.SymbolKind.Interface;
case 'program': return node_1.SymbolKind.Class;
case 'package': return node_1.SymbolKind.Module;
case 'function': return node_1.SymbolKind.Function;
case 'task': return node_1.SymbolKind.Method;
case 'parameter': return node_1.SymbolKind.Property;
case 'localparam': return node_1.SymbolKind.Property;
case 'modport': return node_1.SymbolKind.Field;
case 'struct_union_member': return node_1.SymbolKind.Field;
case 'struct': return node_1.SymbolKind.Struct;
case 'union': return node_1.SymbolKind.Struct;
case 'enum_member': return node_1.SymbolKind.EnumMember;
case 'enum': return node_1.SymbolKind.Enum;
case 'typedef': return node_1.SymbolKind.TypeParameter;
case 'instance':
case 'variable':
default: return node_1.SymbolKind.Variable;
}
}