Skip to content

Commit a8a9e4f

Browse files
committed
feat: update dependencies and improve error handling across various components
1 parent 3e2f43f commit a8a9e4f

23 files changed

+180
-114
lines changed

package-lock.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@
607607
"@types/glob": "^9.0.0",
608608
"@types/mocha": "~10.0.6",
609609
"@types/node": "~22.10.0",
610+
"@types/semver": "^7.7.1",
610611
"@types/vscode": "^1.75.0",
611612
"@types/which": "^3.0.3",
612613
"@typescript-eslint/eslint-plugin": "^8.39.1",

src/BsvProvider.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// SPDX-License-Identifier: MIT
2+
// @ts-nocheck
3+
24
import {
35
SymbolInformation,
46
DocumentSymbol,

src/bsvLanguageServer/bsvLanguage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const trait =
1616
class BsvScope {}
1717

1818
class BsvIdentifier {
19-
identifier: String;
19+
identifier: String = '';
2020
}
2121

2222
const bsvPackageMixin = trait(BsvScope)(trait(BsvIdentifier)(class {}));

src/commands/ModuleInstantiation.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,19 @@ import { Ctags, Symbol } from '../ctags';
66
import { logger } from '../extension';
77

88
export function instantiateModuleInteract() {
9+
if (!vscode.window.activeTextEditor) {
10+
vscode.window.showErrorMessage('No active text editor found');
11+
return;
12+
}
913
let filePath = path.dirname(vscode.window.activeTextEditor.document.fileName);
1014
selectFile(filePath).then((srcpath) => {
15+
if (srcpath === undefined) {
16+
return;
17+
}
1118
instantiateModule(srcpath).then((inst) => {
12-
vscode.window.activeTextEditor.insertSnippet(inst);
19+
if (inst && vscode.window.activeTextEditor) {
20+
vscode.window.activeTextEditor.insertSnippet(inst);
21+
}
1322
});
1423
});
1524
}
@@ -19,12 +28,15 @@ async function instantiateModule(srcpath: string): Promise<vscode.SnippetString
1928
let moduleName: string = '';
2029
let portsName: string[] = [];
2130
let parametersName: string[] = [];
31+
if (!vscode.window.activeTextEditor) {
32+
return undefined;
33+
}
2234
let file: vscode.TextDocument = vscode.window.activeTextEditor.document;
2335
let ctags: ModuleTags = new ModuleTags(logger, file);
2436
logger.info('Executing ctags for module instantiation');
2537
let output = await ctags.execCtags(srcpath);
2638
await ctags.buildSymbolsList(output);
27-
let module: Symbol;
39+
let module: Symbol | undefined;
2840
let modules: Symbol[] = ctags.symbols.filter((tag) => tag.type === 'module');
2941
// No modules found
3042
if (modules.length <= 0) {
@@ -37,17 +49,21 @@ async function instantiateModule(srcpath: string): Promise<vscode.SnippetString
3749
}
3850
// many modules found
3951
else if (modules.length > 1) {
40-
moduleName = await vscode.window.showQuickPick(
52+
const selectedModuleName = await vscode.window.showQuickPick(
4153
ctags.symbols.filter((tag) => tag.type === 'module').map((tag) => tag.name),
4254
{
4355
placeHolder: 'Choose a module to instantiate',
4456
}
4557
);
46-
if (moduleName === undefined) {
58+
if (selectedModuleName === undefined) {
4759
return undefined;
4860
}
61+
moduleName = selectedModuleName;
4962
module = modules.filter((tag) => tag.name === moduleName)[0];
5063
}
64+
if (!module) {
65+
return undefined;
66+
}
5167
let scope = module.parentScope != '' ? module.parentScope + '.' + module.name : module.name;
5268
let ports: Symbol[] = ctags.symbols.filter(
5369
(tag) => tag.type === 'port' && tag.parentType === 'module' && tag.parentScope === scope
@@ -114,6 +130,10 @@ function instantiatePort(ports: string[]): string {
114130
async function selectFile(currentDir?: string): Promise<string | undefined> {
115131
currentDir = currentDir || vscode.workspace.rootPath;
116132

133+
if (!currentDir) {
134+
return undefined;
135+
}
136+
117137
let dirs = getDirectories(currentDir);
118138
// if is subdirectory, add '../'
119139
if (currentDir !== vscode.workspace.rootPath) {
@@ -168,21 +188,21 @@ function getFiles(srcpath: string): string[] {
168188
class ModuleTags extends Ctags {
169189
buildSymbolsList(tags: string): Promise<void> {
170190
if (tags === '') {
171-
return undefined;
191+
return Promise.resolve();
172192
}
173193
// Parse ctags output
174194
let lines: string[] = tags.split(/\r?\n/);
175195
lines.forEach((line) => {
176196
if (line !== '') {
177-
let tag: Symbol = this.parseTagLine(line);
197+
let tag: Symbol | undefined = this.parseTagLine(line);
178198
// add only modules, ports and parameters
179199
// Use 'parameter' type instead of 'constant' after #102
180-
if (tag.type === 'module' || tag.type === 'port' || tag.type === 'parameter') {
200+
if (tag && (tag.type === 'module' || tag.type === 'port' || tag.type === 'parameter')) {
181201
this.symbols.push(tag);
182202
}
183203
}
184204
});
185205
// skip finding end tags
186-
return undefined;
206+
return Promise.resolve();
187207
}
188208
}

src/ctags.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export class Symbol {
3131
this.startPosition = new vscode.Position(startLine, 0);
3232
this.parentScope = parentScope;
3333
this.parentType = parentType;
34-
this.isValid = isValid;
35-
this.endPosition = new vscode.Position(endLine, Number.MAX_VALUE);
34+
this.isValid = isValid ?? false;
35+
this.endPosition = new vscode.Position(endLine ?? startLine, Number.MAX_VALUE);
3636
}
3737

3838
setEndPosition(endLine: number) {
@@ -180,7 +180,7 @@ export class Ctags {
180180
}
181181
}
182182
catch (e) {
183-
this.logger.error('Exception caught: ' + e.message + ' ' + e.data);
183+
this.logger.error('Exception caught: ' + (e instanceof Error ? e.message : String(e)));
184184
}
185185
}
186186
else {
@@ -190,14 +190,14 @@ export class Ctags {
190190
return Promise.resolve('');
191191
}
192192

193-
parseTagLine(line: string): Symbol {
193+
parseTagLine(line: string): Symbol | undefined {
194194
try {
195195
let name, type, pattern, lineNoStr, parentScope, parentType: string;
196196
let scope: string[];
197197
let lineNo: number;
198198
let parts: string[] = line.split('\t');
199199
name = parts[0];
200-
// pattern = parts[2];
200+
pattern = parts[2];
201201
type = parts[3];
202202
// override "type" for parameters (See #102)
203203
if (parts.length == 6 && parts[5] === 'parameter:') {
@@ -233,22 +233,26 @@ export class Ctags {
233233
let lines: string[] = tags.split(/\r?\n/);
234234
lines.forEach((line) => {
235235
if (line !== '') {
236-
this.symbols.push(this.parseTagLine(line));
236+
let tag: Symbol | undefined = this.parseTagLine(line);
237+
if (tag) {
238+
this.symbols.push(tag);
239+
}
237240
}
238241
});
239242

240243
// end tags are not supported yet in ctags. So, using regex
241-
let match;
242-
let endPosition;
244+
let match: RegExpExecArray | null;
245+
let endPosition: vscode.Position;
243246
let text = this.doc.getText();
244247
let eRegex: RegExp = /^(?![\r\n])\s*end(\w*)*[\s:]?/gm;
245248
while ((match = eRegex.exec(text))) {
246249
if (match && typeof match[1] !== 'undefined') {
247250
endPosition = this.doc.positionAt(match.index + match[0].length - 1);
248251
// get the starting symbols of the same type
249252
// doesn't check for begin...end blocks
253+
const matchType = match[1];
250254
let s = this.symbols.filter(
251-
(i) => i.type === match[1] && i.startPosition.isBefore(endPosition) && !i.isValid
255+
(i) => i.type === matchType && i.startPosition.isBefore(endPosition) && !i.isValid
252256
);
253257
if (s.length > 0) {
254258
// get the symbol nearest to the end tag
@@ -272,7 +276,7 @@ export class Ctags {
272276
this.isDirty = false;
273277
}
274278
} catch (e) {
275-
this.logger.error(e.toString());
279+
this.logger.error(String(e));
276280
}
277281
}
278282

@@ -286,7 +290,7 @@ export class Ctags {
286290

287291
export class CtagsManager {
288292
private filemap: Map<vscode.TextDocument, Ctags> = new Map();
289-
private logger: Logger;
293+
private logger!: Logger;
290294

291295
configure(logger: Logger) {
292296
this.logger = logger;
@@ -296,7 +300,7 @@ export class CtagsManager {
296300
}
297301

298302
getCtags(doc: vscode.TextDocument): Ctags {
299-
let ctags: Ctags = this.filemap.get(doc);
303+
let ctags: Ctags | undefined = this.filemap.get(doc);
300304
if (ctags === undefined) {
301305
ctags = new Ctags(this.logger, doc);
302306
this.filemap.set(doc, ctags);
@@ -346,7 +350,7 @@ export class CtagsManager {
346350

347351
let textRange = document.getWordRangeAtPosition(position);
348352
if (!textRange || textRange.isEmpty) {
349-
return undefined;
353+
return [];
350354
}
351355
let targetText = document.getText(textRange);
352356

@@ -366,11 +370,13 @@ export class CtagsManager {
366370
}
367371

368372
// kick off async job for indexing for module.sv
369-
let searchPattern = new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], `**/${moduleToFind}.sv`);
370-
let files = await vscode.workspace.findFiles(searchPattern);
371-
if (files.length !== 0) {
372-
let file = await vscode.workspace.openTextDocument(files[0]);
373-
tasks.push(this.findDefinition(file, targetText));
373+
if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
374+
let searchPattern = new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], `**/${moduleToFind}.sv`);
375+
let files = await vscode.workspace.findFiles(searchPattern);
376+
if (files.length !== 0) {
377+
let file = await vscode.workspace.openTextDocument(files[0]);
378+
tasks.push(this.findDefinition(file, targetText));
379+
}
374380
}
375381

376382
// TODO: use promise.race

src/extension.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,11 @@ function setupLanguageClient(
223223
if (!enabled) {
224224
return;
225225
}
226-
languageClients.get(name).start();
227-
logger.info('"' + name + '" language server started.');
226+
const client = languageClients.get(name);
227+
if (client) {
228+
client.start();
229+
logger.info('"' + name + '" language server started.');
230+
}
228231
}
229232

230233
function initAllLanguageClients() {
@@ -252,10 +255,11 @@ function initAllLanguageClients() {
252255
connectionOptions: {
253256
messageStrategy: {
254257
handleMessage: (message, next) => {
255-
if (Message.isResponse(message) && message.result['capabilities']) {
256-
delete message.result['capabilities']['diagnosticProvider'];
257-
delete message.result['capabilities']['documentFormattingProvider'];
258-
delete message.result['capabilities']['documentRangeFormattingProvider'];
258+
if (Message.isResponse(message) && message.result && typeof message.result === 'object' && 'capabilities' in message.result) {
259+
const result = message.result as any;
260+
delete result['capabilities']['diagnosticProvider'];
261+
delete result['capabilities']['documentFormattingProvider'];
262+
delete result['capabilities']['documentRangeFormattingProvider'];
259263
}
260264
next(message);
261265
},

src/extensionManager.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@ export class ExtensionManager {
1414
this.context = context;
1515
this.extensionID = extensionID;
1616
this.logger = logger;
17-
this.packageJSON = vscode.extensions.getExtension(this.extensionID).packageJSON;
18-
this.extensionPath = vscode.extensions.getExtension(this.extensionID).extensionPath;
17+
const extension = vscode.extensions.getExtension(this.extensionID);
18+
if (!extension) {
19+
throw new Error(`Extension ${extensionID} not found`);
20+
}
21+
this.packageJSON = extension.packageJSON;
22+
this.extensionPath = extension.extensionPath;
1923
}
2024

2125
public isVersionUpdated(): boolean {
@@ -40,7 +44,7 @@ export class ExtensionManager {
4044
if (this.isVersionUpdated()) {
4145
vscode.window
4246
.showInformationMessage(displayName + ' extension has been updated', 'Open Changelog')
43-
.then(function (_: string) {
47+
.then(function (_: string | undefined) {
4448
let changelogUri = vscode.Uri.file(extensionPath + '/CHANGELOG.md');
4549
vscode.workspace.openTextDocument(changelogUri).then((doc) => {
4650
vscode.window.showTextDocument(doc);

src/hover.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export class HoverProvider implements vscode.HoverProvider {
1616
document: vscode.TextDocument,
1717
position: vscode.Position,
1818
_token: vscode.CancellationToken
19-
): vscode.Hover {
19+
): vscode.Hover | undefined {
2020
// get word start and end
2121
let textRange = document.getWordRangeAtPosition(position);
2222

@@ -50,13 +50,12 @@ export class HoverProvider implements vscode.HoverProvider {
5050
return { element: '', comment: '' };
5151
}
5252

53-
let variableType: string;
54-
if (this.lang === 'systemverilog') {
55-
variableType = String.raw`\b(input|output|inout|reg|wire|logic|integer|bit|byte|shortint|int|longint|time|shortreal|real|double|realtime|rand|randc)\b\s+`;
56-
} else if (this.lang === 'verilog') {
57-
variableType = String.raw`\b(input|output|inout|reg|wire|integer|time|real)\b\s+`;
58-
}
59-
let variableTypeStart = '^' + variableType;
53+
const systemverilogTypes = ['input', 'output', 'inout', 'reg', 'wire', 'logic', 'integer', 'bit', 'byte', 'shortint', 'int', 'longint', 'time', 'shortreal', 'real', 'double', 'realtime', 'rand', 'randc'];
54+
const verilogTypes = ['input', 'output', 'inout', 'reg', 'wire', 'integer', 'time', 'real'];
55+
56+
const types = this.lang === 'systemverilog' ? systemverilogTypes : verilogTypes;
57+
const variableType = String.raw`\b(${types.join('|')})\b\s+`;
58+
const variableTypeStart = '^' + variableType;
6059
let paraType = String.raw`^\b(parameter|localparam)\b\s+\b${target}\b`;
6160

6261
let regexTarget = RegExp(String.raw`\b${target}\b`);
@@ -132,6 +131,6 @@ function getSuffixedComment(document: vscode.TextDocument, lineNo: number): stri
132131
if (idx !== -1) {
133132
return line.substring(idx + 2).trim();
134133
} else {
135-
return undefined;
134+
return '';
136135
}
137136
}

src/linter/BaseLinter.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ export default abstract class BaseLinter {
1919
if (path.isAbsolute(inputPath)) {
2020
return inputPath;
2121
}
22+
if (!vscode.workspace.workspaceFolders || vscode.workspace.workspaceFolders.length === 0) {
23+
return inputPath;
24+
}
2225
return path.join(vscode.workspace.workspaceFolders[0].uri.fsPath, inputPath);
2326
}
2427

@@ -31,5 +34,5 @@ export default abstract class BaseLinter {
3134
}
3235

3336
protected abstract convertToSeverity(severityString: string): vscode.DiagnosticSeverity;
34-
protected abstract lint(doc: vscode.TextDocument);
37+
protected abstract lint(doc: vscode.TextDocument): void;
3538
}

0 commit comments

Comments
 (0)