add verilator support
This commit is contained in:
parent
fdacf3f2e1
commit
010a4b6bec
10
package.json
10
package.json
@ -60,7 +60,13 @@
|
|||||||
"scope": "window",
|
"scope": "window",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "",
|
"default": "",
|
||||||
"description": "set the xilinx install path. \n e.g. : D:/APP/vivado_18_3/Vivado/2018.3/bin \n Default path is C:/Xilinx/Vivado/2018.3/bin \n This applies only to WIN For other systems, add it to environment variables"
|
"description": "Set the xilinx install path. Ignore this setting if you add relative path to environment variable PATH \n e.g. : D:/APP/vivado_18_3/Vivado/2018.3/bin \n Default path is C:/Xilinx/Vivado/2018.3/bin"
|
||||||
|
},
|
||||||
|
"prj.modelsim.install.path": {
|
||||||
|
"scope": "window",
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"description": "set the modelsim install path. Ignore this setting if you add relative path to environment variable PATH \n Default path is C:/modeltech64_10.4/win64"
|
||||||
},
|
},
|
||||||
"prj.xilinx.IP.repo.path": {
|
"prj.xilinx.IP.repo.path": {
|
||||||
"scope": "window",
|
"scope": "window",
|
||||||
@ -1046,4 +1052,4 @@
|
|||||||
"vscode-textmate": "^9.0.0",
|
"vscode-textmate": "^9.0.0",
|
||||||
"wavedrom": "^2.9.1"
|
"wavedrom": "^2.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,8 @@ interface BaseManager {
|
|||||||
initialise(): Promise<void>;
|
initialise(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
BaseLinter,
|
BaseLinter,
|
||||||
BaseManager
|
BaseManager
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { All } from '../../../../resources/hdlParser';
|
import { All } from '../../../../resources/hdlParser';
|
||||||
import { isVerilogFile, isVhdlFile } from '../../../hdlFs/file';
|
import { isVerilogFile, isVhdlFile } from '../../../hdlFs/file';
|
||||||
import { Position, Range } from '../../../hdlParser/common';
|
import { Position } from '../../../hdlParser/common';
|
||||||
import { hdlSymbolStorage } from '../core';
|
import { hdlSymbolStorage } from '../core';
|
||||||
import { BaseLinter } from './base';
|
import { BaseLinter } from './base';
|
||||||
import { LspOutput, ReportType } from '../../../global';
|
import { LspOutput, ReportType } from '../../../global';
|
||||||
@ -159,7 +159,12 @@ class DefaultVHDLLinter implements BaseLinter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultVlogLinter = new DefaultVlogLinter();
|
||||||
|
const defaultVHDLLinter = new DefaultVHDLLinter();
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
defaultVlogLinter,
|
||||||
|
defaultVHDLLinter,
|
||||||
DefaultVlogLinter,
|
DefaultVlogLinter,
|
||||||
DefaultVHDLLinter
|
DefaultVHDLLinter
|
||||||
};
|
};
|
||||||
|
@ -28,10 +28,6 @@ class ModelsimLinter implements BaseLinter {
|
|||||||
this.linterArgsMap.set(HdlLangID.Vhdl, ['-quiet', '-nologo', '-2008']);
|
this.linterArgsMap.set(HdlLangID.Vhdl, ['-quiet', '-nologo', '-2008']);
|
||||||
this.linterArgsMap.set(HdlLangID.SystemVerilog, ['-quiet', '-nolog', '-sv']);
|
this.linterArgsMap.set(HdlLangID.SystemVerilog, ['-quiet', '-nolog', '-sv']);
|
||||||
this.linterArgsMap.set(HdlLangID.Unknown, []);
|
this.linterArgsMap.set(HdlLangID.Unknown, []);
|
||||||
|
|
||||||
this.initialise(HdlLangID.Verilog);
|
|
||||||
this.initialise(HdlLangID.Vhdl);
|
|
||||||
this.initialise(HdlLangID.SystemVerilog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -40,16 +36,22 @@ class ModelsimLinter implements BaseLinter {
|
|||||||
const langID = hdlFile.getLanguageId(filePath);
|
const langID = hdlFile.getLanguageId(filePath);
|
||||||
|
|
||||||
// acquire install path
|
// acquire install path
|
||||||
const args = [hdlPath.toSlash(filePath), ...this.linterArgsMap];
|
const linterArgs = this.linterArgsMap.get(langID);
|
||||||
|
|
||||||
|
if (linterArgs === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = [filePath, ...linterArgs];
|
||||||
const executor = this.executableInvokeNameMap.get(langID);
|
const executor = this.executableInvokeNameMap.get(langID);
|
||||||
if (executor !== undefined) {
|
if (executor !== undefined) {
|
||||||
const { stdout, stderr } = await easyExec(executor, args);
|
const { stdout } = await easyExec(executor, args);
|
||||||
if (stdout.length > 0) {
|
if (stdout.length > 0) {
|
||||||
const diagnostics = this.provideDiagnostics(document, stdout);
|
const diagnostics = this.provideDiagnostics(document, stdout);
|
||||||
this.diagnostic.set(document.uri, diagnostics);
|
this.diagnostic.set(document.uri, diagnostics);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LspOutput.report('linter is not available, please check prj.vivado.install.path in your setting', ReportType.Error);
|
LspOutput.report('linter is not available, please check prj.modelsim.install.path in your setting', ReportType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ class ModelsimLinter implements BaseLinter {
|
|||||||
for (const line of stdout.split('\n')) {
|
for (const line of stdout.split('\n')) {
|
||||||
const tokens = line.split(/(Error|Warning).+?(?: *?(?:.+?(?:\\|\/))+.+?\((\d+?)\):|)(?: *?near "(.+?)":|)(?: *?\((.+?)\)|) +?(.+)/gm);
|
const tokens = line.split(/(Error|Warning).+?(?: *?(?:.+?(?:\\|\/))+.+?\((\d+?)\):|)(?: *?near "(.+?)":|)(?: *?\((.+?)\)|) +?(.+)/gm);
|
||||||
|
|
||||||
|
|
||||||
const headerInfo = tokens[0];
|
const headerInfo = tokens[0];
|
||||||
if (headerInfo === 'Error') {
|
if (headerInfo === 'Error') {
|
||||||
const errorLine = parseInt(tokens[2]) - 1;
|
const errorLine = parseInt(tokens[2]) - 1;
|
||||||
@ -93,26 +95,26 @@ class ModelsimLinter implements BaseLinter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getExecutableFilePath(langID: HdlLangID): string | Path | undefined {
|
private getExecutableFilePath(langID: HdlLangID): string | Path | undefined {
|
||||||
// vivado install path stored in prj.vivado.install.path
|
// modelsim install path stored in prj.modelsim.install.path
|
||||||
const vivadoConfig = vscode.workspace.getConfiguration('prj.vivado');
|
const modelsimConfig = vscode.workspace.getConfiguration('prj.modelsim');
|
||||||
const vivadoInstallPath = vivadoConfig.get('install.path', '');
|
const modelsimInstallPath = modelsimConfig.get('install.path', '');
|
||||||
const executorName = this.executableFileMap.get(langID);
|
const executorName = this.executableFileMap.get(langID);
|
||||||
if (executorName === undefined) {
|
if (executorName === undefined) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// e.g. xvlog.bat in windows, xvlog in linux
|
// e.g. vlog.exe in windows, vlog in linux
|
||||||
const fullExecutorName = opeParam.os === 'win32' ? executorName + '.bat' : executorName;
|
const fullExecutorName = opeParam.os === 'win32' ? executorName + '.exe' : executorName;
|
||||||
|
|
||||||
if (vivadoInstallPath.trim() === '' || !fs.existsSync(vivadoInstallPath)) {
|
if (modelsimInstallPath.trim() === '' || !fs.existsSync(modelsimInstallPath)) {
|
||||||
LspOutput.report(`User's Vivado Install Path ${vivadoInstallPath}, which is invalid. Use ${executorName} in default.`, ReportType.Warn);
|
LspOutput.report(`User's modelsim Install Path ${modelsimInstallPath}, which is invalid. Use ${executorName} in default.`, ReportType.Warn);
|
||||||
LspOutput.report('If you have doubts, check prj.vivado.install.path in setting', ReportType.Warn);
|
LspOutput.report('If you have doubts, check prj.modelsim.install.path in setting', ReportType.Warn);
|
||||||
return executorName;
|
return executorName;
|
||||||
} else {
|
} else {
|
||||||
LspOutput.report(`User's Vivado Install Path ${vivadoInstallPath}, which is invalid`);
|
LspOutput.report(`User's modelsim Install Path ${modelsimInstallPath}, which is invalid`);
|
||||||
|
|
||||||
const executorPath = hdlPath.join(
|
const executorPath = hdlPath.join(
|
||||||
hdlPath.toSlash(vivadoInstallPath),
|
hdlPath.toSlash(modelsimInstallPath),
|
||||||
fullExecutorName
|
fullExecutorName
|
||||||
);
|
);
|
||||||
// prevent path like C://stupid name/xxx/xxx/bin
|
// prevent path like C://stupid name/xxx/xxx/bin
|
||||||
@ -127,14 +129,14 @@ class ModelsimLinter implements BaseLinter {
|
|||||||
if (executorPath === undefined) {
|
if (executorPath === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const { stdout, stderr } = await easyExec(executorPath, []);
|
const { stderr } = await easyExec(executorPath, []);
|
||||||
if (stderr.length === 0) {
|
if (stderr.length === 0) {
|
||||||
this.executableInvokeNameMap.set(langID, undefined);
|
this.executableInvokeNameMap.set(langID, undefined);
|
||||||
LspOutput.report(`fail to execute ${executorPath}! Reason: ${stderr}`, ReportType.Error);
|
LspOutput.report(`fail to execute ${executorPath}! Reason: ${stderr}`, ReportType.Error);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
this.executableInvokeNameMap.set(langID, executorPath);
|
this.executableInvokeNameMap.set(langID, executorPath);
|
||||||
LspOutput.report(`success to verify ${executorPath}, linter from vivado is ready to go!`, ReportType.Launch);
|
LspOutput.report(`success to verify ${executorPath}, linter from modelsim is ready to go!`, ReportType.Launch);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +147,9 @@ class ModelsimLinter implements BaseLinter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const modelsimLinter = new ModelsimLinter()
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
modelsimLinter,
|
||||||
ModelsimLinter
|
ModelsimLinter
|
||||||
};
|
};
|
||||||
|
153
src/function/lsp/linter/verilator.ts
Normal file
153
src/function/lsp/linter/verilator.ts
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
import * as vscode from "vscode";
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
import { LspOutput, ReportType, opeParam } from "../../../global";
|
||||||
|
import { Path } from "../../../../resources/hdlParser";
|
||||||
|
import { hdlFile, hdlPath } from "../../../hdlFs";
|
||||||
|
import { easyExec } from "../../../global/util";
|
||||||
|
import { BaseLinter } from "./base";
|
||||||
|
import { HdlLangID } from "../../../global/enum";
|
||||||
|
|
||||||
|
class VerilatorLinter implements BaseLinter {
|
||||||
|
diagnostic: vscode.DiagnosticCollection;
|
||||||
|
executableFileMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>();
|
||||||
|
executableInvokeNameMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>();
|
||||||
|
linterArgsMap: Map<HdlLangID, string[]> = new Map<HdlLangID, string[]>();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.diagnostic = vscode.languages.createDiagnosticCollection();
|
||||||
|
|
||||||
|
// configure map for executable file name
|
||||||
|
this.executableFileMap.set(HdlLangID.Verilog, 'verilator');
|
||||||
|
this.executableFileMap.set(HdlLangID.SystemVerilog, 'verilator');
|
||||||
|
this.executableFileMap.set(HdlLangID.Unknown, undefined);
|
||||||
|
|
||||||
|
// configure map for argruments when lintering
|
||||||
|
this.linterArgsMap.set(HdlLangID.Verilog, ['--lint-only', '-Wall', '-bbox-sys', '--bbox-unsup', '-DGLBL']);
|
||||||
|
this.linterArgsMap.set(HdlLangID.SystemVerilog, ['--lint-only', '-sv', '-Wall', '-bbox-sys', '--bbox-unsup', '-DGLBL']);
|
||||||
|
this.linterArgsMap.set(HdlLangID.Unknown, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async lint(document: vscode.TextDocument) {
|
||||||
|
const filePath = hdlPath.toSlash(document.fileName);
|
||||||
|
const langID = hdlFile.getLanguageId(filePath);
|
||||||
|
|
||||||
|
// acquire install path
|
||||||
|
const linterArgs = this.linterArgsMap.get(langID);
|
||||||
|
|
||||||
|
if (linterArgs === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = [filePath, ...linterArgs];
|
||||||
|
const executor = this.executableInvokeNameMap.get(langID);
|
||||||
|
if (executor !== undefined) {
|
||||||
|
const { stdout } = await easyExec(executor, args);
|
||||||
|
if (stdout.length > 0) {
|
||||||
|
const diagnostics = this.provideDiagnostics(document, stdout);
|
||||||
|
this.diagnostic.set(document.uri, diagnostics);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LspOutput.report('linter is not available, please check prj.verilator.install.path in your setting', ReportType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param document
|
||||||
|
* @param stdout stdout from xvlog
|
||||||
|
* @returns { vscode.Diagnostic[] } linter info
|
||||||
|
*/
|
||||||
|
private provideDiagnostics(document: vscode.TextDocument, stdout: string): vscode.Diagnostic[] {
|
||||||
|
const diagnostics = [];
|
||||||
|
for (const line of stdout.split('\n')) {
|
||||||
|
const tokens = line.split(/(Error|Warning).+?(?: *?(?:.+?(?:\\|\/))+.+?\((\d+?)\):|)(?: *?near "(.+?)":|)(?: *?\((.+?)\)|) +?(.+)/gm);
|
||||||
|
// TODO : make parser of output info from verilator
|
||||||
|
|
||||||
|
const headerInfo = tokens[0];
|
||||||
|
if (headerInfo === 'Error') {
|
||||||
|
const errorLine = parseInt(tokens[2]) - 1;
|
||||||
|
const syntaxInfo = tokens[5];
|
||||||
|
const range = this.makeCorrectRange(document, errorLine);
|
||||||
|
const diag = new vscode.Diagnostic(range, syntaxInfo, vscode.DiagnosticSeverity.Error);
|
||||||
|
diagnostics.push(diag);
|
||||||
|
} else if (headerInfo == 'Warning') {
|
||||||
|
const errorLine = parseInt(tokens[2]) - 1;
|
||||||
|
const syntaxInfo = tokens[5];
|
||||||
|
const range = this.makeCorrectRange(document, errorLine);
|
||||||
|
const diag = new vscode.Diagnostic(range, syntaxInfo, vscode.DiagnosticSeverity.Warning);
|
||||||
|
diagnostics.push(diag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return diagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
|
private makeCorrectRange(document: vscode.TextDocument, line: number): vscode.Range {
|
||||||
|
const startPosition = new vscode.Position(line, 0);
|
||||||
|
const wordRange = document.getWordRangeAtPosition(startPosition, /[`_0-9a-zA-Z]+/);
|
||||||
|
if (wordRange) {
|
||||||
|
return wordRange;
|
||||||
|
} else {
|
||||||
|
return new vscode.Range(startPosition, startPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getExecutableFilePath(langID: HdlLangID): string | Path | undefined {
|
||||||
|
// verilator install path stored in prj.verilator.install.path
|
||||||
|
const verilatorConfig = vscode.workspace.getConfiguration('prj.verilator');
|
||||||
|
const verilatorInstallPath = verilatorConfig.get('install.path', '');
|
||||||
|
const executorName = this.executableFileMap.get(langID);
|
||||||
|
if (executorName === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// e.g. vlog.exe in windows, vlog in linux
|
||||||
|
const fullExecutorName = opeParam.os === 'win32' ? executorName + '.exe' : executorName;
|
||||||
|
|
||||||
|
if (verilatorInstallPath.trim() === '' || !fs.existsSync(verilatorInstallPath)) {
|
||||||
|
LspOutput.report(`User's verilator Install Path ${verilatorInstallPath}, which is invalid. Use ${executorName} in default.`, ReportType.Warn);
|
||||||
|
LspOutput.report('If you have doubts, check prj.verilator.install.path in setting', ReportType.Warn);
|
||||||
|
return executorName;
|
||||||
|
} else {
|
||||||
|
LspOutput.report(`User's verilator Install Path ${verilatorInstallPath}, which is invalid`);
|
||||||
|
|
||||||
|
const executorPath = hdlPath.join(
|
||||||
|
hdlPath.toSlash(verilatorInstallPath),
|
||||||
|
fullExecutorName
|
||||||
|
);
|
||||||
|
// prevent path like C://stupid name/xxx/xxx/bin
|
||||||
|
// blank space
|
||||||
|
const safeExecutorPath = '"' + executorPath + '"';
|
||||||
|
return safeExecutorPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async setExecutableFilePath(executorPath: string | Path | undefined, langID: HdlLangID): Promise<boolean> {
|
||||||
|
if (executorPath === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const { stderr } = await easyExec(executorPath, []);
|
||||||
|
if (stderr.length === 0) {
|
||||||
|
this.executableInvokeNameMap.set(langID, undefined);
|
||||||
|
LspOutput.report(`fail to execute ${executorPath}! Reason: ${stderr}`, ReportType.Error);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.executableInvokeNameMap.set(langID, executorPath);
|
||||||
|
LspOutput.report(`success to verify ${executorPath}, linter from verilator is ready to go!`, ReportType.Launch);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public initialise(langID: HdlLangID) {
|
||||||
|
const executorPath = this.getExecutableFilePath(langID);
|
||||||
|
this.setExecutableFilePath(executorPath, langID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const verilatorLinter = new VerilatorLinter();
|
||||||
|
|
||||||
|
export {
|
||||||
|
verilatorLinter,
|
||||||
|
VerilatorLinter
|
||||||
|
};
|
@ -1,13 +1,92 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { BaseManager } from './base';
|
import { LspOutput, ReportType } from '../../../global';
|
||||||
|
import { HdlLangID } from '../../../global/enum';
|
||||||
|
import { BaseLinter, BaseManager } from './base';
|
||||||
|
import { defaultVlogLinter } from './default';
|
||||||
|
import { modelsimLinter } from './modelsim';
|
||||||
|
import { vivadoLinter } from './vivado';
|
||||||
|
|
||||||
class VhdlLinterManager implements BaseManager {
|
class VhdlLinterManager implements BaseManager {
|
||||||
constructor() {
|
currentLinter: BaseLinter | undefined;
|
||||||
|
activateList: Map<string, boolean> = new Map<string, boolean>();
|
||||||
|
activateLinterName: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.activateList.set('vivado', false);
|
||||||
|
this.activateList.set('modelsim', false);
|
||||||
|
this.activateList.set('default', false);
|
||||||
|
this.activateLinterName = 'default';
|
||||||
|
|
||||||
|
this.updateLinter();
|
||||||
|
|
||||||
|
// update when user's config is changed
|
||||||
|
vscode.workspace.onDidChangeConfiguration(() => {
|
||||||
|
const diagnostor = this.getUserDiagnostorSelection();
|
||||||
|
const lastDiagnostor = this.activateLinterName;
|
||||||
|
if (diagnostor !== lastDiagnostor) {
|
||||||
|
LspOutput.report(`[vhdl lsp manager] detect linter setting changes, switch ${lastDiagnostor} to ${diagnostor}.`, );
|
||||||
|
this.updateLinter();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialise(): Promise<void> {
|
async initialise(): Promise<void> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUserDiagnostorSelection() {
|
||||||
|
const vlogLspConfig = vscode.workspace.getConfiguration('function.lsp.linter.vlog');
|
||||||
|
const diagnostor = vlogLspConfig.get('diagnostor', 'default');
|
||||||
|
return diagnostor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateLinter() {
|
||||||
|
const diagnostor = this.getUserDiagnostorSelection();
|
||||||
|
switch (diagnostor) {
|
||||||
|
case 'vivado': this.activateVivado(); break;
|
||||||
|
case 'modelsim': this.activateModelsim(); break;
|
||||||
|
case 'default': this.activateDefault(); break;
|
||||||
|
case default: this.activateDefault(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public activateVivado() {
|
||||||
|
const selectedLinter = vivadoLinter;
|
||||||
|
|
||||||
|
if (this.activateList.get('vivado') === false) {
|
||||||
|
selectedLinter.initialise(HdlLangID.Verilog);
|
||||||
|
this.activateList.set('vivado', true);
|
||||||
|
LspOutput.report('[vhdl lsp manager] vivado linter has been activated', ReportType.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentLinter = selectedLinter;
|
||||||
|
this.activateLinterName = 'vivado';
|
||||||
|
}
|
||||||
|
|
||||||
|
public activateModelsim() {
|
||||||
|
const selectedLinter = modelsimLinter;
|
||||||
|
|
||||||
|
if (this.activateList.get('modelsim') === false) {
|
||||||
|
selectedLinter.initialise(HdlLangID.Verilog);
|
||||||
|
this.activateList.set('modelsim', true);
|
||||||
|
LspOutput.report('[vhdl lsp manager] modelsim linter has been activated', ReportType.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentLinter = selectedLinter;
|
||||||
|
this.activateLinterName = 'modelsim';
|
||||||
|
}
|
||||||
|
|
||||||
|
public activateDefault() {
|
||||||
|
const selectedLinter = defaultVlogLinter;
|
||||||
|
|
||||||
|
if (this.activateList.get('default') === false) {
|
||||||
|
|
||||||
|
this.activateList.set('default', true);
|
||||||
|
LspOutput.report('[vhdl lsp manager] default build-in linter has been activated', ReportType.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentLinter = selectedLinter;
|
||||||
|
this.activateLinterName = 'default';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,4 +94,4 @@ const vhdlLinterManager = new VhdlLinterManager();
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
vhdlLinterManager
|
vhdlLinterManager
|
||||||
};
|
};
|
||||||
|
@ -29,9 +29,9 @@ class VivadoLinter implements BaseLinter {
|
|||||||
this.linterArgsMap.set(HdlLangID.SystemVerilog, ['--sv', '--nolog']);
|
this.linterArgsMap.set(HdlLangID.SystemVerilog, ['--sv', '--nolog']);
|
||||||
this.linterArgsMap.set(HdlLangID.Unknown, []);
|
this.linterArgsMap.set(HdlLangID.Unknown, []);
|
||||||
|
|
||||||
this.initialise(HdlLangID.Verilog);
|
// this.initialise(HdlLangID.Verilog);
|
||||||
this.initialise(HdlLangID.Vhdl);
|
// this.initialise(HdlLangID.Vhdl);
|
||||||
this.initialise(HdlLangID.SystemVerilog);
|
// this.initialise(HdlLangID.SystemVerilog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -40,10 +40,15 @@ class VivadoLinter implements BaseLinter {
|
|||||||
const langID = hdlFile.getLanguageId(filePath);
|
const langID = hdlFile.getLanguageId(filePath);
|
||||||
|
|
||||||
// acquire install path
|
// acquire install path
|
||||||
const args = [hdlPath.toSlash(filePath), ...this.linterArgsMap];
|
const linterArgs = this.linterArgsMap.get(langID);
|
||||||
|
if (linterArgs === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = [filePath, ...linterArgs];
|
||||||
const executor = this.executableInvokeNameMap.get(langID);
|
const executor = this.executableInvokeNameMap.get(langID);
|
||||||
if (executor !== undefined) {
|
if (executor !== undefined) {
|
||||||
const { stdout, stderr } = await easyExec(executor, args);
|
const { stdout } = await easyExec(executor, args);
|
||||||
if (stdout.length > 0) {
|
if (stdout.length > 0) {
|
||||||
const diagnostics = this.provideDiagnostics(document, stdout);
|
const diagnostics = this.provideDiagnostics(document, stdout);
|
||||||
this.diagnostic.set(document.uri, diagnostics);
|
this.diagnostic.set(document.uri, diagnostics);
|
||||||
@ -122,7 +127,7 @@ class VivadoLinter implements BaseLinter {
|
|||||||
if (executorPath === undefined) {
|
if (executorPath === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const { stdout, stderr } = await easyExec(executorPath, []);
|
const { stderr } = await easyExec(executorPath, []);
|
||||||
if (stderr.length === 0) {
|
if (stderr.length === 0) {
|
||||||
this.executableInvokeNameMap.set(langID, undefined);
|
this.executableInvokeNameMap.set(langID, undefined);
|
||||||
LspOutput.report(`fail to execute ${executorPath}! Reason: ${stderr}`, ReportType.Error);
|
LspOutput.report(`fail to execute ${executorPath}! Reason: ${stderr}`, ReportType.Error);
|
||||||
@ -140,7 +145,9 @@ class VivadoLinter implements BaseLinter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const vivadoLinter = new VivadoLinter();
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
vivadoLinter,
|
||||||
VivadoLinter
|
VivadoLinter
|
||||||
};
|
};
|
||||||
|
@ -1,14 +1,92 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { BaseManager } from './base';
|
import { LspOutput, ReportType } from '../../../global';
|
||||||
|
import { HdlLangID } from '../../../global/enum';
|
||||||
|
import { BaseLinter, BaseManager } from './base';
|
||||||
|
import { defaultVlogLinter } from './default';
|
||||||
|
import { modelsimLinter } from './modelsim';
|
||||||
|
import { vivadoLinter } from './vivado';
|
||||||
|
|
||||||
class VlogLinterManager implements BaseManager {
|
class VlogLinterManager implements BaseManager {
|
||||||
|
currentLinter: BaseLinter | undefined;
|
||||||
|
activateList: Map<string, boolean> = new Map<string, boolean>();
|
||||||
|
activateLinterName: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.lsp.verilog.linter');
|
this.activateList.set('vivado', false);
|
||||||
const
|
this.activateList.set('modelsim', false);
|
||||||
|
this.activateList.set('default', false);
|
||||||
|
this.activateLinterName = 'default';
|
||||||
|
|
||||||
|
this.updateLinter();
|
||||||
|
|
||||||
|
// update when user's config is changed
|
||||||
|
vscode.workspace.onDidChangeConfiguration(() => {
|
||||||
|
const diagnostor = this.getUserDiagnostorSelection();
|
||||||
|
const lastDiagnostor = this.activateLinterName;
|
||||||
|
if (diagnostor !== lastDiagnostor) {
|
||||||
|
LspOutput.report(`detect linter setting changes, switch ${lastDiagnostor} to ${diagnostor}.`, );
|
||||||
|
this.updateLinter();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialise(): Promise<void> {
|
async initialise(): Promise<void> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public getUserDiagnostorSelection() {
|
||||||
|
const vlogLspConfig = vscode.workspace.getConfiguration('function.lsp.linter.vlog');
|
||||||
|
const diagnostor = vlogLspConfig.get('diagnostor', 'default');
|
||||||
|
return diagnostor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateLinter() {
|
||||||
|
const diagnostor = this.getUserDiagnostorSelection();
|
||||||
|
switch (diagnostor) {
|
||||||
|
case 'vivado': this.activateVivado(); break;
|
||||||
|
case 'modelsim': this.activateModelsim(); break;
|
||||||
|
case 'default': this.activateDefault(); break;
|
||||||
|
case default: this.activateDefault(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public activateVivado() {
|
||||||
|
const selectedLinter = vivadoLinter;
|
||||||
|
|
||||||
|
if (this.activateList.get('vivado') === false) {
|
||||||
|
selectedLinter.initialise(HdlLangID.Verilog);
|
||||||
|
this.activateList.set('vivado', true);
|
||||||
|
LspOutput.report('vivado linter has been activated', ReportType.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentLinter = selectedLinter;
|
||||||
|
this.activateLinterName = 'vivado';
|
||||||
|
}
|
||||||
|
|
||||||
|
public activateModelsim() {
|
||||||
|
const selectedLinter = modelsimLinter;
|
||||||
|
|
||||||
|
if (this.activateList.get('modelsim') === false) {
|
||||||
|
selectedLinter.initialise(HdlLangID.Verilog);
|
||||||
|
this.activateList.set('modelsim', true);
|
||||||
|
LspOutput.report('modelsim linter has been activated', ReportType.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentLinter = selectedLinter;
|
||||||
|
this.activateLinterName = 'modelsim';
|
||||||
|
}
|
||||||
|
|
||||||
|
public activateDefault() {
|
||||||
|
const selectedLinter = defaultVlogLinter;
|
||||||
|
|
||||||
|
if (this.activateList.get('default') === false) {
|
||||||
|
|
||||||
|
this.activateList.set('default', true);
|
||||||
|
LspOutput.report('default build-in linter has been activated', ReportType.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentLinter = selectedLinter;
|
||||||
|
this.activateLinterName = 'default';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user