完成诊断器架构重新设计

This commit is contained in:
锦恢 2024-12-06 23:23:50 +08:00
parent aacd135f36
commit 11b5349582
16 changed files with 364 additions and 134 deletions

View File

@ -81,5 +81,13 @@
"error.simulation.error-happen-run-command": "Fehler bei der Icarus-Simulation:",
"info.command.structure.transform-xilinx-to-standard": "Konvertiere Xilinx-Projektstruktur in Digital IDE-Standardstruktur",
"error.command.structure.not-valid-xilinx-project": "Das aktuelle Projekt ist kein gültiges Xilinx-Projekt, die Konvertierung ist fehlgeschlagen!",
"info.common.codedoc": "Code-Dokumentation"
"info.common.codedoc": "Code-Dokumentation",
"info.linter.pick-for-verilog": "Wählen Sie einen Diagnostiker für Verilog-Code aus",
"info.command.loading": "Wird geladen",
"info.linter.pick-for-system-verilog": "Wählen Sie einen Diagnostiker für System Verilog-Code",
"info.linter.pick-for-vhdl": "Wählen Sie einen Diagnostiker für VHDL-Code aus",
"info.linter.vivado.xvlog-name": "Vivado-Diagnosetools",
"info.common.some-is-ready": "{0} ist bereit",
"info.common.not-available": "{0} ist derzeit nicht verfügbar",
"info.common.linter-name": "Diagnosetools"
}

View File

@ -81,5 +81,13 @@
"error.simulation.error-happen-run-command": "Error during Icarus simulation:",
"info.command.structure.transform-xilinx-to-standard": "Converting Xilinx project structure to Digital IDE standard structure",
"error.command.structure.not-valid-xilinx-project": "The current project is not a valid Xilinx project, the conversion failed!",
"info.common.codedoc": "Code Documentation"
"info.common.codedoc": "Code Documentation",
"info.linter.pick-for-verilog": "Select a diagnostician for Verilog code",
"info.command.loading": "Loading",
"info.linter.pick-for-system-verilog": "Select a diagnostician for System Verilog code",
"info.linter.pick-for-vhdl": "Select a diagnostician for VHDL code",
"info.linter.vivado.xvlog-name": "Vivado diagnostic tools",
"info.common.some-is-ready": "{0} is ready",
"info.common.not-available": "{0} is currently unavailable",
"info.common.linter-name": "Diagnostic tools"
}

View File

@ -81,5 +81,13 @@
"error.simulation.error-happen-run-command": "Icarusシミュレーション中にエラーが発生しました",
"info.command.structure.transform-xilinx-to-standard": "Xilinx プロジェクト構造を Digital IDE 標準構造に変換しています",
"error.command.structure.not-valid-xilinx-project": "現在のプロジェクトは有効なXilinxプロジェクトではありません、変換に失敗しました",
"info.common.codedoc": "コードドキュメント"
"info.common.codedoc": "コードドキュメント",
"info.linter.pick-for-verilog": "Verilogコードの診断機能を選択してください",
"info.command.loading": "読み込み中",
"info.linter.pick-for-system-verilog": "System Verilog コードの診断機能を選択",
"info.linter.pick-for-vhdl": "VHDLコードの診断機能を選択してください",
"info.linter.vivado.xvlog-name": "Vivado診断ツール",
"info.common.some-is-ready": "{0} は準備ができています",
"info.common.not-available": "{0} は現在使用できません",
"info.common.linter-name": "診断ツール"
}

View File

@ -81,5 +81,13 @@
"error.simulation.error-happen-run-command": "Icarus 仿真时,出现错误:",
"info.command.structure.transform-xilinx-to-standard": "正在将 Xilinx 项目结构转变为 Digital IDE 标准结构",
"error.command.structure.not-valid-xilinx-project": "当前项目不是一个有效的 Xilinx 项目,转换失败!",
"info.common.codedoc": "代码文档"
"info.common.codedoc": "代码文档",
"info.linter.pick-for-verilog": "为 Verilog 代码选择一个诊断器",
"info.command.loading": "加载中",
"info.linter.pick-for-system-verilog": "为 System Verilog 代码选择一个诊断器",
"info.linter.pick-for-vhdl": "为 VHDL 代码选择一个诊断器",
"info.linter.vivado.xvlog-name": "vivado 诊断工具",
"info.common.some-is-ready": "{0} 已经准备就绪",
"info.common.not-available": "{0} 目前不可用",
"info.common.linter-name": "诊断工具"
}

View File

@ -81,5 +81,13 @@
"error.simulation.error-happen-run-command": "Icarus 模擬時,出現錯誤:",
"info.command.structure.transform-xilinx-to-standard": "正在將 Xilinx 專案結構轉變為 Digital IDE 標準結構",
"error.command.structure.not-valid-xilinx-project": "當前專案不是一個有效的 Xilinx 專案,轉換失敗!",
"info.common.codedoc": "程式碼文件"
"info.common.codedoc": "程式碼文件",
"info.linter.pick-for-verilog": "為 Verilog 程式碼選擇一個診斷器",
"info.command.loading": "載入中",
"info.linter.pick-for-system-verilog": "為 System Verilog 程式碼選擇一個診斷器",
"info.linter.pick-for-vhdl": "為VHDL代碼選擇一個診斷器",
"info.linter.vivado.xvlog-name": "Vivado診斷工具",
"info.common.some-is-ready": "{0} 已經準備就緒",
"info.common.not-available": "{0} 目前無法使用",
"info.common.linter-name": "診斷工具"
}

View File

@ -70,6 +70,16 @@
"default": "C:/modeltech64_10.4/win64",
"description": "%digital-ide.prj.modelsim.install.path.title%"
},
"digital-ide.prj.verible.install.path": {
"type": "string",
"default": "",
"description": "%digital-ide.prj.verible.install.path.title%"
},
"digital-ide.prj.verilator.install.path": {
"type": "string",
"default": "",
"description": "%digital-ide.prj.verilator.install.path.title%"
},
"digital-ide.prj.xilinx.IP.repo.path": {
"type": "string",
"default": "",
@ -150,9 +160,9 @@
"default": "<div style=\"font-size: 9px; margin-left: 1cm;\"> <span class='title'></span></div> <div style=\"font-size: 9px; margin-left: auto; margin-right: 1cm; \"> <span class='date'></span></div>",
"description": "%digital-ide.function.doc.pdf.footerTemplate.title%"
},
"digital-ide.function.simulate.icarus.installPath": {
"digital-ide.prj.iverilog.install.path": {
"type": "string",
"description": "%digital-ide.function.simulate.icarus.installPath.title%"
"description": "%digital-ide.prj.iverilog.install.path.title%"
},
"digital-ide.function.simulate.simulationHome": {
"type": "string",
@ -228,14 +238,16 @@
"digital-ide.function.lsp.linter.vlog.diagnostor": {
"type": "string",
"enumDescriptions": [
"use diagnostor in vivado",
"use diagnostor in modelsim",
"use our buildin diagnostor"
"vivado",
"modelsim",
"verilator",
"verible"
],
"enum": [
"vivado",
"modelsim",
"default"
"verilator",
"verible"
],
"default": "default",
"description": "%digital-ide.function.lsp.linter.vlog.diagnostor.title%"

View File

@ -71,7 +71,7 @@
"digital-ide.function.doc.pdf.margin.left.title": "top margin of exported pdf, unit cm",
"digital-ide.function.doc.pdf.headerTemplate.title": "html template of header, if displayHeaderFooter is set to false, this setting will be ignored",
"digital-ide.function.doc.pdf.footerTemplate.title": "html template of footer, if displayHeaderFooter is set to false, this setting will be ignored",
"digital-ide.function.simulate.icarus.installPath.title": "Path of install path of iverilog components, if set to \"\", then iverilog and vvp in environment will be used for simulation. Otherwise, ones that in the install path will be used.",
"digital-ide.prj.iverilog.install.path.title": "Path of install path of iverilog components, if set to \"\", then iverilog and vvp in environment will be used for simulation. Otherwise, ones that in the install path will be used.",
"digital-ide.function.simulate.simulationHome.title": "Path of simulation folder, .vvp and other file during simulation will be generated here",
"digital-ide.function.simulate.gtkwavePath.title": "Absolute path of launch path of gtkwave software",
"digital-ide.function.simulate.xilinxLibPath.title": "Path of Xilinx library for simulation",
@ -92,5 +92,7 @@
"digital-ide.function.instantiation.autoNetOutputDeclaration.title": "auto declare output type nets in the scope when instantiation happens.",
"fpga-support.onTypeFormattingTriggerCharacters.title": "Trigger characters for onTypeFormatting",
"digital-ide.function.lsp.file-parse-maxsize.title": "",
"digital-ide.structure.from-xilinx-to-standard.title": "Konvertieren Sie Xilinx-Projekte in die Digital IDE-Standardprojektstruktur"
"digital-ide.structure.from-xilinx-to-standard.title": "Konvertieren Sie Xilinx-Projekte in die Digital IDE-Standardprojektstruktur",
"digital-ide.prj.verible.install.path.title": "",
"digital-ide.prj.verilator.install.path.title": ""
}

View File

@ -71,7 +71,7 @@
"digital-ide.function.doc.pdf.margin.left.title": "エクスポートされた PDF の左余白、単位 cm",
"digital-ide.function.doc.pdf.headerTemplate.title": "ヘッダーの HTML テンプレート、displayHeaderFooter が false に設定されている場合、この設定は無視されます",
"digital-ide.function.doc.pdf.footerTemplate.title": "フッターの HTML テンプレート、displayHeaderFooter が false に設定されている場合、この設定は無視されます",
"digital-ide.function.simulate.icarus.installPath.title": "Icarus Verilog コンポーネントのインストールパス、空に設定されている場合、環境の iverilog と vvp がシミュレーションに使用されます。それ以外の場合、インストールパスのコンポーネントが使用されます。",
"digital-ide.prj.iverilog.install.path.title": "Icarus Verilog コンポーネントのインストールパス、空に設定されている場合、環境の iverilog と vvp がシミュレーションに使用されます。それ以外の場合、インストールパスのコンポーネントが使用されます。",
"digital-ide.function.simulate.simulationHome.title": "シミュレーションフォルダのパス、シミュレーション中の .vvp およびその他のファイルがここに生成されます",
"digital-ide.function.simulate.gtkwavePath.title": "gtkwave ソフトウェアの起動パスの絶対パス",
"digital-ide.function.simulate.xilinxLibPath.title": "シミュレーション用の Xilinx ライブラリのパス",
@ -92,5 +92,7 @@
"digital-ide.function.instantiation.autoNetOutputDeclaration.title": "インスタンス化が発生したときにスコープ内で出力タイプのネットを自動的に宣言します。",
"fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting のトリガー文字",
"digital-ide.function.lsp.file-parse-maxsize.title": "",
"digital-ide.structure.from-xilinx-to-standard.title": "Xilinx プロジェクトを Digital IDE 標準プロジェクト構造に変換する"
"digital-ide.structure.from-xilinx-to-standard.title": "Xilinx プロジェクトを Digital IDE 標準プロジェクト構造に変換する",
"digital-ide.prj.verible.install.path.title": "",
"digital-ide.prj.verilator.install.path.title": ""
}

View File

@ -71,7 +71,7 @@
"digital-ide.function.doc.pdf.margin.left.title": "Left margin of the exported PDF, unit cm",
"digital-ide.function.doc.pdf.headerTemplate.title": "HTML template of the header, if displayHeaderFooter is set to false, this setting will be ignored",
"digital-ide.function.doc.pdf.footerTemplate.title": "HTML template of the footer, if displayHeaderFooter is set to false, this setting will be ignored",
"digital-ide.function.simulate.icarus.installPath.title": "Installation path of Icarus Verilog components, if set to empty, the iverilog and vvp in the environment will be used for simulation. Otherwise, the components in the installation path will be used.",
"digital-ide.prj.iverilog.install.path.title": "Installation path of Icarus Verilog components, if set to empty, the iverilog and vvp in the environment will be used for simulation. Otherwise, the components in the installation path will be used.",
"digital-ide.function.simulate.simulationHome.title": "Path of the simulation folder, .vvp and other files during simulation will be generated here",
"digital-ide.function.simulate.gtkwavePath.title": "Absolute path of the launch path of the gtkwave software",
"digital-ide.function.simulate.xilinxLibPath.title": "Path of the Xilinx library for simulation",
@ -92,5 +92,7 @@
"digital-ide.function.instantiation.autoNetOutputDeclaration.title": "Automatically declare output type nets in the scope when instantiation happens.",
"fpga-support.onTypeFormattingTriggerCharacters.title": "Trigger characters for onTypeFormatting",
"digital-ide.function.lsp.file-parse-maxsize.title": "",
"digital-ide.structure.from-xilinx-to-standard.title": "Convert Xilinx projects to Digital IDE standard project structure"
"digital-ide.structure.from-xilinx-to-standard.title": "Convert Xilinx projects to Digital IDE standard project structure",
"digital-ide.prj.verible.install.path.title": "",
"digital-ide.prj.verilator.install.path.title": ""
}

View File

@ -71,7 +71,7 @@
"digital-ide.function.doc.pdf.margin.left.title": "导出的 PDF 的左边距,单位 cm",
"digital-ide.function.doc.pdf.headerTemplate.title": "页眉的 HTML 模板,如果 displayHeaderFooter 设置为 false则此设置将被忽略",
"digital-ide.function.doc.pdf.footerTemplate.title": "页脚的 HTML 模板,如果 displayHeaderFooter 设置为 false则此设置将被忽略",
"digital-ide.function.simulate.icarus.installPath.title": "Icarus Verilog 组件的安装路径,如果设置为空,则使用环境中的 iverilog 和 vvp 进行仿真。否则,将使用安装路径中的组件。",
"digital-ide.prj.iverilog.install.path.title": "Icarus Verilog 组件的安装路径,如果设置为空,则使用环境中的 iverilog 和 vvp 进行仿真。否则,将使用安装路径中的组件。",
"digital-ide.function.simulate.simulationHome.title": "仿真文件夹路径,仿真期间的 .vvp 和其他文件将生成在此处",
"digital-ide.function.simulate.gtkwavePath.title": "gtkwave 软件的启动路径的绝对路径",
"digital-ide.function.simulate.xilinxLibPath.title": "仿真用 Xilinx 库的路径",
@ -92,5 +92,7 @@
"digital-ide.function.instantiation.autoNetOutputDeclaration.title": "在实例化发生时自动在作用域中声明输出类型的网络。",
"fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting 的触发字符",
"digital-ide.function.lsp.file-parse-maxsize.title": "最大解析的文件阈值,大小超出这个值的文件不会被解析。单位为 MB必须是整数。默认为 1MB",
"digital-ide.structure.from-xilinx-to-standard.title": "将 Xilinx 项目转换成 Digital IDE 标准项目结构"
"digital-ide.structure.from-xilinx-to-standard.title": "将 Xilinx 项目转换成 Digital IDE 标准项目结构",
"digital-ide.prj.verible.install.path.title": "",
"digital-ide.prj.verilator.install.path.title": ""
}

View File

@ -71,7 +71,7 @@
"digital-ide.function.doc.pdf.margin.left.title": "導出的 PDF 的左邊距,單位 cm",
"digital-ide.function.doc.pdf.headerTemplate.title": "頁眉的 HTML 模板,如果 displayHeaderFooter 設置為 false則此設置將被忽略",
"digital-ide.function.doc.pdf.footerTemplate.title": "頁腳的 HTML 模板,如果 displayHeaderFooter 設置為 false則此設置將被忽略",
"digital-ide.function.simulate.icarus.installPath.title": "Icarus Verilog 組件的安裝路徑,如果設置為空,則使用環境中的 iverilog 和 vvp 進行仿真。否則,將使用安裝路徑中的組件。",
"digital-ide.prj.iverilog.install.path.title": "Icarus Verilog 組件的安裝路徑,如果設置為空,則使用環境中的 iverilog 和 vvp 進行仿真。否則,將使用安裝路徑中的組件。",
"digital-ide.function.simulate.simulationHome.title": "仿真文件夾路徑,仿真期間的 .vvp 和其他文件將生成在此處",
"digital-ide.function.simulate.gtkwavePath.title": "gtkwave 軟件的啟動路徑的絕對路徑",
"digital-ide.function.simulate.xilinxLibPath.title": "仿真用 Xilinx 庫的路徑",
@ -92,5 +92,7 @@
"digital-ide.function.instantiation.autoNetOutputDeclaration.title": "在實例化發生時自動在作用域中聲明輸出類型的網絡。",
"fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting 的觸發字符",
"digital-ide.function.lsp.file-parse-maxsize.title": "",
"digital-ide.structure.from-xilinx-to-standard.title": "將 Xilinx 專案轉換成 Digital IDE 標準專案結構"
"digital-ide.structure.from-xilinx-to-standard.title": "將 Xilinx 專案轉換成 Digital IDE 標準專案結構",
"digital-ide.prj.verible.install.path.title": "",
"digital-ide.prj.verilator.install.path.title": ""
}

View File

@ -1,6 +1,8 @@
import * as vscode from 'vscode';
import { LanguageClient } from 'vscode-languageclient/node';
import { UpdateConfigurationType } from '../../global/lsp';
import * as linterCommand from '../../function/lsp/linter/command';
import { HdlLangID } from '../../global/enum';
interface ConfigItem {
name: string,
@ -10,6 +12,7 @@ interface ConfigItem {
type CommonValue = string | boolean | number;
export function registerConfigurationUpdater(client: LanguageClient, packageJson: any) {
// 常规 lsp 相关的配置
const lspConfigures: ConfigItem[] = [];
const properties = packageJson?.contributes?.configuration?.properties;
const dideConfig = vscode.workspace.getConfiguration('digital-ide');
@ -21,12 +24,34 @@ export function registerConfigurationUpdater(client: LanguageClient, packageJson
}
}
const supportLinters: linterCommand.SupportLinterName[] = ['iverilog', 'vivado', 'modelsim', 'verible', 'verilator'];
// 初始化,配置参数全部同步到后端
client.sendRequest(UpdateConfigurationType, {
configs: lspConfigures,
configType: 'lsp'
});
// 初始化,配置全部 linter 到后端
updateLinterConfiguration(
client,
linterCommand.VLOG_LINTER_CONFIG_NAME + '.diagnostor',
getCurrentLinterName(HdlLangID.Verilog)
);
updateLinterConfiguration(
client,
linterCommand.SVLOG_LINTER_CONFIG_NAME + '.diagnostor',
getCurrentLinterName(HdlLangID.SystemVerilog)
);
updateLinterConfiguration(
client,
linterCommand.VHDL_LINTER_CONFIG_NAME + '.diagnostor',
getCurrentLinterName(HdlLangID.Vhdl)
);
// 监听配置文件的变化,变化时需要做出的行为
vscode.workspace.onDidChangeConfiguration(async event => {
const changeConfigs: ConfigItem[] = [];
const dideConfig = vscode.workspace.getConfiguration('');
@ -43,5 +68,86 @@ export function registerConfigurationUpdater(client: LanguageClient, packageJson
configType: 'lsp'
});
}
const currentLinterConfiguration = {
vlog: getCurrentLinterName(HdlLangID.Verilog),
svlog: getCurrentLinterName(HdlLangID.SystemVerilog),
vhdl: getCurrentLinterName(HdlLangID.Vhdl)
};
// 对于诊断器路径的修改
for (const linterName of supportLinters) {
const configuratioName = linterCommand.LinterInstallPathConfigurationNames[linterName];
if (event.affectsConfiguration(configuratioName)) {
// 查看谁使用了这个诊断器,更新它的基本信息
if (linterName === currentLinterConfiguration.vlog) {
await updateLinterConfiguration(
client,
linterCommand.VLOG_LINTER_CONFIG_NAME + '.diagnostor',
linterName
);
}
if (linterName === currentLinterConfiguration.svlog) {
await updateLinterConfiguration(
client,
linterCommand.SVLOG_LINTER_CONFIG_NAME + '.diagnostor',
linterName
);
}
if (linterName === currentLinterConfiguration.vhdl) {
await updateLinterConfiguration(
client,
linterCommand.VHDL_LINTER_CONFIG_NAME + '.diagnostor',
linterName
);
}
}
}
});
}
function getCurrentLinterName(langID: HdlLangID): linterCommand.SupportLinterName {
switch (langID) {
case HdlLangID.Verilog:
return vscode.workspace.getConfiguration().get<linterCommand.SupportLinterName>(
linterCommand.VLOG_LINTER_CONFIG_NAME + '.diagnostor',
'vivado'
);
case HdlLangID.Vhdl:
return vscode.workspace.getConfiguration().get<linterCommand.SupportLinterName>(
linterCommand.VHDL_LINTER_CONFIG_NAME + '.diagnostor',
'vivado'
);
case HdlLangID.SystemVerilog:
return vscode.workspace.getConfiguration().get<linterCommand.SupportLinterName>(
linterCommand.SVLOG_LINTER_CONFIG_NAME + '.diagnostor',
'vivado'
);
default:
break;
}
return 'vivado';
}
async function updateLinterConfiguration(
client: LanguageClient,
configurationName: string,
linterName: linterCommand.SupportLinterName
) {
const configuratioName = linterCommand.LinterInstallPathConfigurationNames[linterName];
const linterPath = vscode.workspace.getConfiguration().get<string>(configuratioName, '');
await client.sendRequest(UpdateConfigurationType, {
configs: [
{ name: configurationName, value: linterName },
{ name: 'path', value: linterPath }
],
configType: 'linter'
});
}

View File

@ -1,106 +1,132 @@
import * as vscode from 'vscode';
import * as fs from 'fs';
import { vivadoLinter } from './vivado';
import { modelsimLinter } from './modelsim';
import { verilatorLinter } from './verilator';
import { HdlLangID } from '../../../global/enum';
import { vlogLinterManager } from './vlog';
import { vhdlLinterManager } from './vhdl';
import { easyExec } from '../../../global/util';
import { LspOutput } from '../../../global';
import { t } from '../../../i18n';
import { LspClient } from '../../../global';
import { LinterStatusRequestType, UpdateConfigurationType } from '../../../global/lsp';
import { LanguageClient } from 'vscode-languageclient/node';
let _selectVlogLinter: string | null = null;
let _selectVhdlLinter: string | null = null;
export let _selectVlogLinterItem: LinterItem | null = null;
export let _selectSvlogLinterItem: LinterItem | null = null;
export let _selectVhdlLinterItem: LinterItem | null = null;
export const VLOG_LINTER_CONFIG_NAME = 'digital-ide.function.lsp.linter.vlog';
export const VHDL_LINTER_CONFIG_NAME = 'digital-ide.function.lsp.linter.vhdl';
export const SVLOG_LINTER_CONFIG_NAME = 'digital-ide.function.lsp.linter.svlog';
// 第三方诊断器路径的相关配置
// iverilog digital-ide.prj.iverilog.install.path
// vivado digital-ide.prj.vivado.install.path
// modelsim digital-ide.prj.modelsim.install.path
// verible digital-ide.prj.verible.install.path
// verilator digital-ide.prj.verilator.install.path
export type SupportLinterName = 'iverilog' | 'vivado' | 'modelsim' | 'verible' | 'verilator';
export const LinterInstallPathConfigurationNames: Record<SupportLinterName, string> = {
iverilog: 'digital-ide.prj.iverilog.install.path',
vivado: 'digital-ide.prj.vivado.install.path',
modelsim: 'digital-ide.prj.modelsim.install.path',
verible: 'digital-ide.prj.verible.install.path',
verilator: 'digital-ide.prj.verilator.install.path'
};
interface LinterItem extends vscode.QuickPickItem {
name: string
linterPath: string
available: boolean
}
async function makeDefaultPickItem(): Promise<LinterItem> {
return {
label: '$(getting-started-beginner) default',
name: 'default',
available: true,
description: 'Digital-IDE build in diagnostic tool',
detail: 'inner build is ready'
};
}
async function makeLinterNamePickItem(
client: LanguageClient,
langID: HdlLangID,
linterName: SupportLinterName
): Promise<LinterItem> {
const configuration = vscode.workspace.getConfiguration();
const linterInstallConfigurationName = LinterInstallPathConfigurationNames[linterName];
const linterPath = configuration.get<string>(linterInstallConfigurationName, '');
async function makeVivadoPickItem(langID: HdlLangID): Promise<LinterItem> {
const executablePath = vivadoLinter.getExecutableFilePath(langID);
const linterName = vivadoLinter.executableFileMap.get(langID);
if (executablePath) {
const { stderr } = await easyExec(executablePath, []);
if (stderr.length > 0) {
return {
label: '$(extensions-warning-message) vivado',
name: 'vivado',
available: false,
description: `vivado diagnostic tool ${linterName}`,
detail: `${executablePath} is not available`
};
}
const linterStatus = await client.sendRequest(LinterStatusRequestType, {
languageId: langID,
linterName,
linterPath
});
return {
label: '$(getting-started-beginner) ' + linterName,
name: linterName,
linterPath,
available: linterStatus.available,
description: linterName + ' ' + t('info.common.linter-name') + ' ' + linterStatus.toolName,
detail: t('info.common.some-is-ready', linterStatus.invokeName)
}
return {
label: '$(getting-started-beginner) vivado',
name: 'vivado',
available: true,
description: `vivado diagnostic tool ${linterName}`,
detail: `${executablePath} is ready`
};
}
async function makeModelsimPickItem(langID: HdlLangID): Promise<LinterItem> {
const executablePath = modelsimLinter.getExecutableFilePath(langID);
const linterName = modelsimLinter.executableFileMap.get(langID);
if (executablePath) {
const { stderr } = await easyExec(executablePath, []);
if (stderr.length > 0) {
return {
label: '$(extensions-warning-message) modelsim',
name: 'modelsim',
available: false,
description: `modelsim diagnostic tool ${linterName}`,
detail: `${executablePath} is not available`
};
}
async function makeLinterOptions(
client: LanguageClient,
langID: HdlLangID,
linters: SupportLinterName[]
) {
const pools = [];
for (const name of linters) {
pools.push(makeLinterNamePickItem(client, langID, name))
}
return {
label: '$(getting-started-beginner) modelsim',
name: 'modelsim',
available: true,
description: `modelsim diagnostic tool ${linterName}`,
detail: `${executablePath} is ready`
};
const items = [];
for (const p of pools) {
items.push(await p);
}
return items;
}
async function pickVlogLinter() {
/**
* @description verilog
*/
export async function pickVlogLinter() {
const pickWidget = vscode.window.createQuickPick<LinterItem>();
pickWidget.placeholder = 'select a linter for verilog code diagnostic';
pickWidget.placeholder = t('info.linter.pick-for-verilog');
pickWidget.canSelectMany = false;
const client = LspClient.DigitalIDE;
if (!client) {
// 尚未启动,退出
return;
}
await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: 'Parsing local environment ...',
title: t('info.command.loading'),
cancellable: true
}, async () => {
pickWidget.items = [
await makeDefaultPickItem(),
await makeVivadoPickItem(HdlLangID.Verilog),
await makeModelsimPickItem(HdlLangID.Verilog)
];
pickWidget.items = await makeLinterOptions(client, HdlLangID.Verilog, [
'iverilog',
'modelsim',
'verible',
'verilator',
'vivado'
]);
});
pickWidget.onDidChangeSelection(items => {
const selectedItem = items[0];
_selectVlogLinter = selectedItem.name;
_selectVlogLinterItem = items[0];
});
pickWidget.onDidAccept(() => {
if (_selectVlogLinter) {
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vlog');
vlogLspConfig.update('diagnostor', _selectVlogLinter);
pickWidget.onDidAccept(async () => {
if (_selectVlogLinterItem) {
const linterConfiguration = vscode.workspace.getConfiguration(VLOG_LINTER_CONFIG_NAME);
linterConfiguration.update('diagnostor', _selectVlogLinterItem.name);
await LspClient.DigitalIDE?.sendRequest(UpdateConfigurationType, {
configs: [
{ name: VLOG_LINTER_CONFIG_NAME + '.diagnostor', value: _selectVlogLinterItem.name },
{ name: 'path', value: _selectVlogLinterItem.linterPath }
],
configType: 'linter'
});
pickWidget.hide();
}
});
@ -108,34 +134,50 @@ async function pickVlogLinter() {
pickWidget.show();
}
async function pickSvlogLinter() {
/**
* @description system verilog
*/
export async function pickSvlogLinter() {
const pickWidget = vscode.window.createQuickPick<LinterItem>();
pickWidget.placeholder = 'select a linter for verilog code diagnostic';
pickWidget.placeholder = t('info.linter.pick-for-system-verilog');
pickWidget.canSelectMany = false;
const client = LspClient.DigitalIDE;
if (!client) {
// 尚未启动,退出
return;
}
await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: 'Parsing local environment ...',
title: t("info.command.loading"),
cancellable: true
}, async () => {
pickWidget.items = [
// TODO : add this if system verilog is supported
// await makeDefaultPickItem(),
await makeVivadoPickItem(HdlLangID.Verilog),
await makeModelsimPickItem(HdlLangID.Verilog)
];
pickWidget.items = await makeLinterOptions(client, HdlLangID.SystemVerilog, [
'modelsim',
'verible',
'verilator',
'vivado'
]);
});
pickWidget.onDidChangeSelection(items => {
const selectedItem = items[0];
_selectVlogLinter = selectedItem.name;
_selectSvlogLinterItem = items[0];
});
pickWidget.onDidAccept(() => {
if (_selectVlogLinter) {
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.svlog');
vlogLspConfig.update('diagnostor', _selectVlogLinter);
pickWidget.onDidAccept(async () => {
if (_selectSvlogLinterItem) {
const linterConfiguration = vscode.workspace.getConfiguration(SVLOG_LINTER_CONFIG_NAME);
linterConfiguration.update('diagnostor', _selectSvlogLinterItem.name);
await LspClient.DigitalIDE?.sendRequest(UpdateConfigurationType, {
configs: [
{ name: SVLOG_LINTER_CONFIG_NAME + '.diagnostor', value: _selectSvlogLinterItem.name },
{ name: 'path', value: _selectSvlogLinterItem.linterPath }
],
configType: 'linter'
});
pickWidget.hide();
}
});
@ -143,44 +185,51 @@ async function pickSvlogLinter() {
pickWidget.show();
}
async function pickVhdlLinter() {
/**
* @description vhdl
*/
export async function pickVhdlLinter() {
const pickWidget = vscode.window.createQuickPick<LinterItem>();
pickWidget.placeholder = 'select a linter for code diagnostic';
pickWidget.placeholder = t('info.linter.pick-for-vhdl');
pickWidget.canSelectMany = false;
const client = LspClient.DigitalIDE;
if (!client) {
// 尚未启动,退出
return;
}
await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: 'Parsing local environment ...',
title: t("info.command.loading"),
cancellable: true
}, async () => {
pickWidget.items = [
await makeDefaultPickItem(),
await makeVivadoPickItem(HdlLangID.Vhdl),
await makeModelsimPickItem(HdlLangID.Vhdl)
];
pickWidget.items = await makeLinterOptions(client, HdlLangID.Vhdl, [
'modelsim',
'vivado'
]);
});
pickWidget.onDidChangeSelection(items => {
const selectedItem = items[0];
_selectVlogLinter = selectedItem.name;
_selectVhdlLinterItem = items[0];
});
pickWidget.onDidAccept(() => {
if (_selectVlogLinter) {
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vhdl');
vlogLspConfig.update('diagnostor', _selectVlogLinter);
pickWidget.onDidAccept(async () => {
if (_selectVhdlLinterItem) {
const linterConfiguration = vscode.workspace.getConfiguration(VHDL_LINTER_CONFIG_NAME);
linterConfiguration.update('diagnostor', _selectVhdlLinterItem.name);
await LspClient.DigitalIDE?.sendRequest(UpdateConfigurationType, {
configs: [
{ name: VHDL_LINTER_CONFIG_NAME + '.diagnostor', value: _selectVhdlLinterItem.name },
{ name: 'path', value: _selectVhdlLinterItem.linterPath },
],
configType: 'linter'
});
pickWidget.hide();
}
});
pickWidget.show();
}
export {
pickVlogLinter,
pickVhdlLinter,
pickSvlogLinter
};

View File

@ -119,7 +119,7 @@ class Simulate {
}
}
simConfig.installPath = setting.get('digital-ide.function.simulate.icarus.installPath', '');
simConfig.installPath = setting.get('digital-ide.prj.iverilog.install.path', '');
if (simConfig.installPath !== '' && !hdlFile.isDir(simConfig.installPath)) {
MainOutput.report(`install path ${simConfig.installPath} is illegal`, {
level: ReportType.Error,

View File

@ -229,7 +229,7 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
const firstTopIcon = this.makeFirstTopIconName(type);
// 将 topModuleItemList 中的 first top 元素调整到第一个位置
const dataItem = topModuleItemList.filter(item => item.name === firstTop.name && item.path === firstTop.path)[0];
const dataItem = topModuleItemList.filter(item => item.name === firstTop!.name && item.path === firstTop!.path)[0];
dataItem.icon = firstTopIcon;
let newTopModuleItemList = [dataItem];
newTopModuleItemList = newTopModuleItemList.concat(topModuleItemList.filter(item => item !== dataItem));

View File

@ -29,6 +29,7 @@ export const DoFastRequestType = new RequestType<IDoFastParam, Fast, void
export const UpdateConfigurationType = new RequestType<IUpdateConfigurationParam, void, void>('api/update-configuration');
export const DoPrimitivesJudgeType = new RequestType<IDoPrimitivesJudgeParam, boolean, void>('api/do-primitives-judge');
export const SyncFastRequestType = new RequestType<ISyncFastParam, Fast, void>('api/sync-fast');
export const LinterStatusRequestType = new RequestType<ILinterStatusRequestType, LinterToolStatus, void>('api/linter-status');
export interface ITextDocumentItem {
uri: vscode.Uri,
@ -47,6 +48,7 @@ export interface ICommonParam {
param: string
}
export interface IUpdateConfigurationParam {
configs: {
name: string,
@ -55,6 +57,17 @@ export interface IUpdateConfigurationParam {
configType: string
}
export interface ILinterStatusRequestType {
languageId: string,
linterName: string,
linterPath: string
}
interface LinterToolStatus {
toolName: string,
available: boolean,
invokeName: string
}
export interface IDoPrimitivesJudgeParam {
name: string