From 8046a1eb00a4b3f30778971a556d116b0c3ab3a9 Mon Sep 17 00:00:00 2001 From: LSTM-Kirigaya <1193466151@qq.com> Date: Sat, 7 Dec 2024 23:39:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=AF=8A=E6=96=AD=E5=99=A8?= =?UTF-8?q?=E5=A4=9A=E7=AB=AF=E9=85=8D=E7=BD=AE=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n/bundle.l10n.de.json | 4 +- l10n/bundle.l10n.en.json | 4 +- l10n/bundle.l10n.ja.json | 4 +- l10n/bundle.l10n.zh-cn.json | 4 +- l10n/bundle.l10n.zh-tw.json | 4 +- package.json | 90 ++++----- package.nls.de.json | 13 +- package.nls.ja.json | 13 +- package.nls.json | 13 +- package.nls.zh-cn.json | 13 +- package.nls.zh-tw.json | 13 +- src/function/index.ts | 11 -- src/function/lsp-client/config.ts | 128 +++++++------ src/function/lsp-client/index.ts | 7 +- src/function/lsp/linter/base.ts | 20 -- src/function/lsp/linter/command.ts | 235 ------------------------ src/function/lsp/linter/common.ts | 112 ++++++++++++ src/function/lsp/linter/default.ts | 166 ----------------- src/function/lsp/linter/index.ts | 15 +- src/function/lsp/linter/manager.ts | 261 +++++++++++++++++++++++++++ src/function/lsp/linter/modelsim.ts | 3 +- src/function/lsp/linter/svlog.ts | 202 --------------------- src/function/lsp/linter/verilator.ts | 3 +- src/function/lsp/linter/vhdl.ts | 202 --------------------- src/function/lsp/linter/vivado.ts | 3 +- src/function/lsp/linter/vlog.ts | 202 --------------------- src/hdlParser/core.ts | 3 - src/monitor/hdl.ts | 11 -- 28 files changed, 550 insertions(+), 1209 deletions(-) delete mode 100644 src/function/lsp/linter/base.ts delete mode 100644 src/function/lsp/linter/command.ts create mode 100644 src/function/lsp/linter/common.ts delete mode 100644 src/function/lsp/linter/default.ts create mode 100644 src/function/lsp/linter/manager.ts delete mode 100644 src/function/lsp/linter/svlog.ts delete mode 100644 src/function/lsp/linter/vhdl.ts delete mode 100644 src/function/lsp/linter/vlog.ts diff --git a/l10n/bundle.l10n.de.json b/l10n/bundle.l10n.de.json index b47a6fd..22670bb 100644 --- a/l10n/bundle.l10n.de.json +++ b/l10n/bundle.l10n.de.json @@ -89,5 +89,7 @@ "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" + "info.common.linter-name": "Diagnosetools", + "info.linter.finish-init": "Initialisierung des Diagnosewerkzeugs {0} abgeschlossen, aktueller Name des Diagnosewerkzeugs {1}", + "error.linter.status-bar.tooltip": "Kann Diagnose für {0} nicht abrufen" } \ No newline at end of file diff --git a/l10n/bundle.l10n.en.json b/l10n/bundle.l10n.en.json index 134401d..ea02a69 100644 --- a/l10n/bundle.l10n.en.json +++ b/l10n/bundle.l10n.en.json @@ -89,5 +89,7 @@ "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" + "info.common.linter-name": "Diagnostic tools", + "info.linter.finish-init": "Completed initialization of the {0} diagnostic tool, current name of the diagnostic tool {1}", + "error.linter.status-bar.tooltip": "Unable to get {0} diagnoser" } \ No newline at end of file diff --git a/l10n/bundle.l10n.ja.json b/l10n/bundle.l10n.ja.json index 38f6811..81132eb 100644 --- a/l10n/bundle.l10n.ja.json +++ b/l10n/bundle.l10n.ja.json @@ -89,5 +89,7 @@ "info.linter.vivado.xvlog-name": "Vivado診断ツール", "info.common.some-is-ready": "{0} は準備ができています", "info.common.not-available": "{0} は現在使用できません", - "info.common.linter-name": "診断ツール" + "info.common.linter-name": "診断ツール", + "info.linter.finish-init": "{0} 診断ツールの初期化が完了しました。現在の診断ツールの名前は {1} です", + "error.linter.status-bar.tooltip": "{0} 診断機能を取得できません" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json index 9aa4855..3c87324 100644 --- a/l10n/bundle.l10n.zh-cn.json +++ b/l10n/bundle.l10n.zh-cn.json @@ -89,5 +89,7 @@ "info.linter.vivado.xvlog-name": "vivado 诊断工具", "info.common.some-is-ready": "{0} 已经准备就绪", "info.common.not-available": "{0} 目前不可用", - "info.common.linter-name": "诊断工具" + "info.common.linter-name": "诊断工具", + "info.linter.finish-init": "完成 {0} 诊断器的初始化,当前诊断器的名字 {1}", + "error.linter.status-bar.tooltip": "无法获取 {0} 诊断器" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-tw.json b/l10n/bundle.l10n.zh-tw.json index d642891..2f502d5 100644 --- a/l10n/bundle.l10n.zh-tw.json +++ b/l10n/bundle.l10n.zh-tw.json @@ -89,5 +89,7 @@ "info.linter.vivado.xvlog-name": "Vivado診斷工具", "info.common.some-is-ready": "{0} 已經準備就緒", "info.common.not-available": "{0} 目前無法使用", - "info.common.linter-name": "診斷工具" + "info.common.linter-name": "診斷工具", + "info.linter.finish-init": "完成 {0} 診斷器的初始化,當前診斷器的名字 {1}", + "error.linter.status-bar.tooltip": "無法取得 {0} 診斷器" } \ No newline at end of file diff --git a/package.json b/package.json index c25fbb6..6b83a7d 100644 --- a/package.json +++ b/package.json @@ -235,68 +235,70 @@ "type": "boolean", "default": true }, - "digital-ide.function.lsp.linter.vlog.diagnostor": { + "digital-ide.function.lsp.linter.verilog.diagnostor": { "type": "string", "enumDescriptions": [ + "iverilog (© Icarus Verilog Project)", + "xvlog (© Xilinx, Inc.)", + "vlog (© Mentor Graphics Corporation)", + "verilator (© Verilator Project)", + "verible-verilog-syntax (© Google LLC)" + ], + "enum": [ + "iverilog", "vivado", "modelsim", "verilator", "verible" ], - "enum": [ - "vivado", - "modelsim", - "verilator", - "verible" - ], - "default": "default", - "description": "%digital-ide.function.lsp.linter.vlog.diagnostor.title%" - }, - "digital-ide.function.lsp.linter.svlog.diagnostor": { - "type": "string", - "enumDescriptions": [ - "use diagnostor in vivado", - "use diagnostor in modelsim", - "use our buildin diagnostor" - ], - "enum": [ - "vivado", - "modelsim", - "default" - ], - "default": "default", - "description": "%digital-ide.function.lsp.linter.svlog.diagnostor.title%" - }, - "digital-ide.function.lsp.linter.vhdl.diagnostor": { - "type": "string", - "enumDescriptions": [ - "use diagnostor in vivado", - "use diagnostor in modelsim", - "use our buildin diagnostor" - ], - "enum": [ - "vivado", - "modelsim", - "default" - ], - "default": "default", - "description": "%digital-ide.function.lsp.linter.vhdl.diagnostor.title%" + "default": "vivado", + "description": "%digital-ide.function.lsp.linter.verilog.diagnostor.title%" }, "digital-ide.function.lsp.linter.systemverilog.diagnostor": { "type": "string", "enumDescriptions": [ - "use diagnostor in vivado", - "use diagnostor in modelsim", - "use our buildin diagnostor" + "xvlog (© Xilinx, Inc.)", + "vlog (© Mentor Graphics Corporation)", + "verilator (© Verilator Project)", + "verible-verilog-syntax (© Google LLC)" ], "enum": [ "vivado", "modelsim", - "default" + "verilator", + "verible" ], - "default": "default", + "default": "vivado", "description": "%digital-ide.function.lsp.linter.systemverilog.diagnostor.title%" }, + "digital-ide.function.lsp.linter.vhdl.diagnostor": { + "type": "string", + "enumDescriptions": [ + "xvlog (© Xilinx, Inc.)", + "vlog (© Mentor Graphics Corporation)" + ], + "enum": [ + "vivado", + "modelsim" + ], + "default": "vivado", + "description": "%digital-ide.function.lsp.linter.vhdl.diagnostor.title%" + }, + "digital-ide.function.lsp.linter.linter-mode": { + "type": "string", + "enumDescriptions": [ + "%digital-ide.function.lsp.linter.linter-mode.0.title%", + "%digital-ide.function.lsp.linter.linter-mode.1.title%", + "%digital-ide.function.lsp.linter.linter-mode.2.title%" + ], + "enum": [ + "full", + "single", + "shutdown" + ], + "default": "full", + "description": "%digital-ide.function.lsp.linter.linter-mode.title%" + }, "digital-ide.function.instantiation.addComment": { "description": "%digital-ide.function.instantiation.addComment.title%", "type": "boolean", diff --git a/package.nls.de.json b/package.nls.de.json index fca8684..cd4515b 100644 --- a/package.nls.de.json +++ b/package.nls.de.json @@ -84,15 +84,18 @@ "digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "Indentation", "digital-ide.function.lsp.completion.vlog.auto-add-include.title": "`include \"xxx.v\" will be added to the top of the file automatically", "digital-ide.function.lsp.completion.vlog.auto-add-output-declaration.title": "complete everything invoking a module needs including paramters and ports", - "digital-ide.function.lsp.linter.vlog.diagnostor.title": "choose diagnostor to do linter in editing verilog", - "digital-ide.function.lsp.linter.svlog.diagnostor.title": "choose diagnostor to do linter in editing verilog", + "digital-ide.function.lsp.linter.verilog.diagnostor.title": "choose diagnostor to do linter in editing verilog", + "digital-ide.function.lsp.linter.systemverilog.diagnostor.title": "choose diagnostor to do linter in editing verilog", "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "choose diagnostor to do linter in editing vhdl", - "digital-ide.function.lsp.linter.systemverilog.diagnostor.title": "choose diagnostor to do linter in editing systemverilog", "digital-ide.function.instantiation.addComment.title": "add comment like // ports, // input, // output when doing instantiation, including completion for module invoking", "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.prj.verible.install.path.title": "", - "digital-ide.prj.verilator.install.path.title": "" + "digital-ide.prj.verible.install.path.title": "Installationsverzeichnispfad für verible, also der absolute Pfad des Ordners, der die ausführbare Datei verible-verilog-syntax enthält. Wenn nicht angegeben, wird standardmäßig verible-verilog-syntax für die Diagnose verwendet.", + "digital-ide.prj.verilator.install.path.title": "Installationsverzeichnispfad für verilator, also der absolute Pfad des Ordners, der die ausführbare Datei verilator enthält. Wenn nicht angegeben, wird standardmäßig verilator für die Diagnose verwendet.", + "digital-ide.function.lsp.linter.linter-mode.title": "Diagnosemodus des Linters festlegen", + "digital-ide.function.lsp.linter.linter-mode.0.title": "Diagnostizieren Sie alle Designquellen direkt und melden Sie Fehler, unabhängig davon, ob die Dateien geöffnet sind.", + "digital-ide.function.lsp.linter.linter-mode.1.title": "Wenn eine einzelne Datei geschlossen ist, wird der entsprechende Fehler entfernt, und nur die geöffnete Datei wird diagnostiziert.", + "digital-ide.function.lsp.linter.linter-mode.2.title": "Global deaktiviert, d.h. für das gesamte Projekt werden keine Projektfehler gemeldet." } \ No newline at end of file diff --git a/package.nls.ja.json b/package.nls.ja.json index e2b1ba1..07812bd 100644 --- a/package.nls.ja.json +++ b/package.nls.ja.json @@ -84,15 +84,18 @@ "digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "インデント", "digital-ide.function.lsp.completion.vlog.auto-add-include.title": "モジュールの自動補完をトリガーするとき、トップの include マクロにインスタンス化されたモジュールがあるファイルが含まれていない場合、ファイルの先頭に `include \"xxx.v\" を自動的に追加します", "digital-ide.function.lsp.completion.vlog.auto-add-output-declaration.title": "モジュールの自動補完をトリガーするとき、インスタンス化されたモジュールの上に output タイプの信号の宣言を自動的に生成します", - "digital-ide.function.lsp.linter.vlog.diagnostor.title": "Verilog 編集時のリンターを行う診断器を選択します", - "digital-ide.function.lsp.linter.svlog.diagnostor.title": "SystemVerilog 編集時のリンターを行う診断器を選択します", - "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "VHDL 編集時のリンターを行う診断器を選択します", + "digital-ide.function.lsp.linter.verilog.diagnostor.title": "Verilog 編集時のリンターを行う診断器を選択します", "digital-ide.function.lsp.linter.systemverilog.diagnostor.title": "SystemVerilog 編集時のリンターを行う診断器を選択します", + "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "VHDL 編集時のリンターを行う診断器を選択します", "digital-ide.function.instantiation.addComment.title": "インスタンス化時に // ポート, // 入力, // 出力 のようなコメントを追加し、モジュール呼び出しの補完を含みます", "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.prj.verible.install.path.title": "", - "digital-ide.prj.verilator.install.path.title": "" + "digital-ide.prj.verible.install.path.title": "verible のインストールディレクトリパス。つまり、verible-verilog-syntax 実行ファイルを含むフォルダの絶対パス。指定しない場合、デフォルトで verible-verilog-syntax が診断に使用されます。", + "digital-ide.prj.verilator.install.path.title": "verilator のインストールディレクトリパス。つまり、verilator 実行ファイルを含むフォルダの絶対パス。指定しない場合、デフォルトで verilator が診断に使用されます。", + "digital-ide.function.lsp.linter.linter-mode.title": "リンターの診断モードを指定", + "digital-ide.function.lsp.linter.linter-mode.0.title": "すべての設計ソースを直接診断し、エラーを報告します。ファイルが開いているかどうかに関係なく。", + "digital-ide.function.lsp.linter.linter-mode.1.title": "単一のファイルが閉じられた場合、対応するエラーが削除され、開いているファイルのみが診断されます。", + "digital-ide.function.lsp.linter.linter-mode.2.title": "グローバルに無効化され、プロジェクト全体でプロジェクトエラーが報告されません。" } \ No newline at end of file diff --git a/package.nls.json b/package.nls.json index 966de39..144768e 100644 --- a/package.nls.json +++ b/package.nls.json @@ -84,15 +84,18 @@ "digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "Indentation", "digital-ide.function.lsp.completion.vlog.auto-add-include.title": "When triggering module auto-completion, if the top include macro does not include the file where the instantiated module is located, automatically add `include \"xxx.v\" at the top of the file", "digital-ide.function.lsp.completion.vlog.auto-add-output-declaration.title": "When triggering module auto-completion, automatically generate the declaration of output type signals above the instantiated module", - "digital-ide.function.lsp.linter.vlog.diagnostor.title": "Choose the diagnostor to do linter in editing Verilog", - "digital-ide.function.lsp.linter.svlog.diagnostor.title": "Choose the diagnostor to do linter in editing SystemVerilog", - "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "Choose the diagnostor to do linter in editing VHDL", + "digital-ide.function.lsp.linter.verilog.diagnostor.title": "Choose the diagnostor to do linter in editing Verilog", "digital-ide.function.lsp.linter.systemverilog.diagnostor.title": "Choose the diagnostor to do linter in editing SystemVerilog", + "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "Choose the diagnostor to do linter in editing VHDL", "digital-ide.function.instantiation.addComment.title": "Add comments like // ports, // input, // output when doing instantiation, including completion for module invoking", "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.prj.verible.install.path.title": "", - "digital-ide.prj.verilator.install.path.title": "" + "digital-ide.prj.verible.install.path.title": "Installation directory path for verible, which is the absolute path of the folder containing the verible-verilog-syntax executable. If not specified, verible-verilog-syntax will be used for diagnostics by default.", + "digital-ide.prj.verilator.install.path.title": "Installation directory path for verilator, which is the absolute path of the folder containing the verilator executable. If not specified, verilator will be used for diagnostics by default.", + "digital-ide.function.lsp.linter.linter-mode.title": "Specify the diagnostic mode of the linter", + "digital-ide.function.lsp.linter.linter-mode.0.title": "Diagnose all design sources directly and report errors, regardless of whether the files are open.", + "digital-ide.function.lsp.linter.linter-mode.1.title": "When a single file is closed, the corresponding error is removed, and only the file that is opened is diagnosed.", + "digital-ide.function.lsp.linter.linter-mode.2.title": "Globally disabled, meaning no project errors are reported for the entire project." } \ No newline at end of file diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index 3ef0456..056b4f9 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -84,15 +84,18 @@ "digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "缩进", "digital-ide.function.lsp.completion.vlog.auto-add-include.title": "触发模块的自动补全时,如果顶部 include 宏中没有包含被例化模块所在的文件,则自动在文件顶部添加 `include \"xxx.v\"", "digital-ide.function.lsp.completion.vlog.auto-add-output-declaration.title": "触发模块的自动补全时,在例化模块上方自动生成 output 类型信号的申明", - "digital-ide.function.lsp.linter.vlog.diagnostor.title": "选择编辑 Verilog 时的诊断器进行语法检查", - "digital-ide.function.lsp.linter.svlog.diagnostor.title": "选择编辑 SystemVerilog 时的诊断器进行语法检查", - "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "选择编辑 VHDL 时的诊断器进行语法检查", + "digital-ide.function.lsp.linter.verilog.diagnostor.title": "选择编辑 Verilog 时的诊断器进行语法检查", "digital-ide.function.lsp.linter.systemverilog.diagnostor.title": "选择编辑 SystemVerilog 时的诊断器进行语法检查", + "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "选择编辑 VHDL 时的诊断器进行语法检查", "digital-ide.function.instantiation.addComment.title": "在进行实例化时添加注释,如 // 端口, // 输入, // 输出,包括模块调用的完成", "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.prj.verible.install.path.title": "", - "digital-ide.prj.verilator.install.path.title": "" + "digital-ide.prj.verible.install.path.title": "verible 的安装目录路径,也就是包含 verible-verilog-syntax 可执行文件的文件夹的绝对路径。如果不指定,默认采用 verible-verilog-syntax 执行诊断。", + "digital-ide.prj.verilator.install.path.title": "verilator 的安装目录路径,也就是包含了 verilator 可执行文件的文件夹的绝对路径。不如不指定,默认采用 verilator 执行诊断。", + "digital-ide.function.lsp.linter.linter-mode.title": "指定诊断器的诊断模式", + "digital-ide.function.lsp.linter.linter-mode.0.title": "将所有设计源直接进行诊断,并报错,无论文件是否打开。", + "digital-ide.function.lsp.linter.linter-mode.1.title": "单文件关闭时,对应报错去除,打开哪个文件就对哪个文件进行诊断。", + "digital-ide.function.lsp.linter.linter-mode.2.title": "全局关闭,即整个工程都不进行工程报错。" } \ No newline at end of file diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index e26f5a1..de81213 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -84,15 +84,18 @@ "digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "縮進", "digital-ide.function.lsp.completion.vlog.auto-add-include.title": "觸發模塊的自動補全時,如果頂部 include 宏中沒有包含被例化模塊所在的文件,則自動在文件頂部添加 `include \"xxx.v\"", "digital-ide.function.lsp.completion.vlog.auto-add-output-declaration.title": "觸發模塊的自動補全時,在例化模塊上方自動生成 output 類型信號的申明", - "digital-ide.function.lsp.linter.vlog.diagnostor.title": "選擇編輯 Verilog 時的診斷器進行語法檢查", - "digital-ide.function.lsp.linter.svlog.diagnostor.title": "選擇編輯 SystemVerilog 時的診斷器進行語法檢查", - "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "選擇編輯 VHDL 時的診斷器進行語法檢查", + "digital-ide.function.lsp.linter.verilog.diagnostor.title": "選擇編輯 Verilog 時的診斷器進行語法檢查", "digital-ide.function.lsp.linter.systemverilog.diagnostor.title": "選擇編輯 SystemVerilog 時的診斷器進行語法檢查", + "digital-ide.function.lsp.linter.vhdl.diagnostor.title": "選擇編輯 VHDL 時的診斷器進行語法檢查", "digital-ide.function.instantiation.addComment.title": "在進行實例化時添加註釋,如 // 端口, // 輸入, // 輸出,包括模塊調用的完成", "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.prj.verible.install.path.title": "", - "digital-ide.prj.verilator.install.path.title": "" + "digital-ide.prj.verible.install.path.title": "verible 的安裝目錄路徑,也就是包含 verible-verilog-syntax 可執行文件的文件夾的絕對路徑。如果不指定,默認採用 verible-verilog-syntax 執行診斷。", + "digital-ide.prj.verilator.install.path.title": "verilator 的安裝目錄路徑,也就是包含了 verilator 可執行文件的文件夾的絕對路徑。不如不指定,默認採用 verilator 執行診斷。", + "digital-ide.function.lsp.linter.linter-mode.title": "指定診斷器的診斷模式", + "digital-ide.function.lsp.linter.linter-mode.0.title": "將所有設計源直接進行診斷,並報錯,無論文件是否打開。", + "digital-ide.function.lsp.linter.linter-mode.1.title": "單文件關閉時,對應報錯去除,打開哪個文件就對哪個文件進行診斷。", + "digital-ide.function.lsp.linter.linter-mode.2.title": "全局關閉,即整個工程都不進行工程報錯。" } \ No newline at end of file diff --git a/src/function/index.ts b/src/function/index.ts index af46f69..0b61fd6 100644 --- a/src/function/index.ts +++ b/src/function/index.ts @@ -8,7 +8,6 @@ import * as treeView from './treeView'; import { tclCompletionProvider } from './lsp/completion/tcl'; import * as lspFormatter from '../../resources/formatter'; import * as lspTranslator from '../../resources/translator'; -import * as lspLinter from './lsp/linter'; import * as tool from './tool'; @@ -119,16 +118,6 @@ function registerLsp(context: vscode.ExtensionContext, version: string) { // tcl lsp vscode.languages.registerCompletionItemProvider(tclSelector, tclCompletionProvider); - - // lsp linter - // make first symbols in workspace - lspLinter.vlogLinterManager.initialise(); - lspLinter.vhdlLinterManager.initialise(); - lspLinter.svlogLinterManager.initialise(); - - vscode.commands.registerCommand('digital-ide.lsp.vlog.linter.pick', lspLinter.pickVlogLinter); - vscode.commands.registerCommand('digital-ide.lsp.vhdl.linter.pick', lspLinter.pickVhdlLinter); - vscode.commands.registerCommand('digital-ide.lsp.svlog.linter.pick', lspLinter.pickSvlogLinter); } diff --git a/src/function/lsp-client/config.ts b/src/function/lsp-client/config.ts index 0925374..43f318e 100644 --- a/src/function/lsp-client/config.ts +++ b/src/function/lsp-client/config.ts @@ -1,8 +1,9 @@ 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 * as Linter from '../lsp/linter/common'; import { HdlLangID } from '../../global/enum'; +import * as lspLinter from '../lsp/linter'; interface ConfigItem { name: string, @@ -11,7 +12,13 @@ interface ConfigItem { type CommonValue = string | boolean | number; -export function registerConfigurationUpdater(client: LanguageClient, packageJson: any) { +/** + * @description 注册配置文件变动时发生的操作 + * 该操作一定发生在 lsp 启动后。 + * @param client + * @param packageJson + */ +export async function registerConfigurationUpdater(client: LanguageClient, packageJson: any) { // 常规 lsp 相关的配置 const lspConfigures: ConfigItem[] = []; const properties = packageJson?.contributes?.configuration?.properties; @@ -24,31 +31,31 @@ export function registerConfigurationUpdater(client: LanguageClient, packageJson } } - const supportLinters: linterCommand.SupportLinterName[] = ['iverilog', 'vivado', 'modelsim', 'verible', 'verilator']; + const supportLinters: Linter.SupportLinterName[] = ['iverilog', 'vivado', 'modelsim', 'verible', 'verilator']; // 初始化,配置参数全部同步到后端 - client.sendRequest(UpdateConfigurationType, { + await client.sendRequest(UpdateConfigurationType, { configs: lspConfigures, configType: 'lsp' }); // 初始化,配置全部 linter 到后端 - updateLinterConfiguration( + await updateLinterConfiguration( client, - linterCommand.VLOG_LINTER_CONFIG_NAME + '.diagnostor', - getCurrentLinterName(HdlLangID.Verilog) + Linter.getLinterConfigurationName(HdlLangID.Verilog), + Linter.getLinterName(HdlLangID.Verilog) ); - updateLinterConfiguration( + await updateLinterConfiguration( client, - linterCommand.SVLOG_LINTER_CONFIG_NAME + '.diagnostor', - getCurrentLinterName(HdlLangID.SystemVerilog) + Linter.getLinterConfigurationName(HdlLangID.SystemVerilog), + Linter.getLinterName(HdlLangID.SystemVerilog) ); - updateLinterConfiguration( + await updateLinterConfiguration( client, - linterCommand.VHDL_LINTER_CONFIG_NAME + '.diagnostor', - getCurrentLinterName(HdlLangID.Vhdl) + Linter.getLinterConfigurationName(HdlLangID.Vhdl), + Linter.getLinterName(HdlLangID.Vhdl) ); // 监听配置文件的变化,变化时需要做出的行为 @@ -69,80 +76,69 @@ export function registerConfigurationUpdater(client: LanguageClient, packageJson }); } - const currentLinterConfiguration = { - vlog: getCurrentLinterName(HdlLangID.Verilog), - svlog: getCurrentLinterName(HdlLangID.SystemVerilog), - vhdl: getCurrentLinterName(HdlLangID.Vhdl) + // 本次更新时,当前各个语言正在使用的诊断器的名字的映射表 + // 因为 getLinterName 需要进行一次映射,此处为后续的遍历预缓存一波 + const currentLinterConfiguration: Record = { + [HdlLangID.Verilog]: Linter.getLinterName(HdlLangID.Verilog), + [HdlLangID.SystemVerilog]: Linter.getLinterName(HdlLangID.SystemVerilog), + [HdlLangID.Vhdl]: Linter.getLinterName(HdlLangID.Vhdl), + [HdlLangID.Unknown]: HdlLangID.Unknown }; + // 需要讨论的可能受到配置文件更新影响 linter 功能的语言列表 + const affectsLangIDs = [HdlLangID.Verilog, HdlLangID.SystemVerilog, HdlLangID.Vhdl]; + // 对于诊断器路径的修改 for (const linterName of supportLinters) { - const configuratioName = linterCommand.LinterInstallPathConfigurationNames[linterName]; + const configuratioName = Linter.getLinterInstallConfigurationName(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 - ); + for (const langID of affectsLangIDs) { + if (linterName === currentLinterConfiguration[langID]) { + const linterConfigurationName = Linter.getLinterConfigurationName(langID); + await updateLinterConfiguration(client, linterConfigurationName, linterName); + } } } } - }); } -function getCurrentLinterName(langID: HdlLangID): linterCommand.SupportLinterName { - switch (langID) { - case HdlLangID.Verilog: - return vscode.workspace.getConfiguration().get( - linterCommand.VLOG_LINTER_CONFIG_NAME + '.diagnostor', - 'vivado' - ); +export async function registerLinter(client: LanguageClient) { + // 初始化,配置全部 linter 到 linterManager + lspLinter.vlogLinterManager.start(client); + lspLinter.vhdlLinterManager.start(client); + lspLinter.svlogLinterManager.start(client); - case HdlLangID.Vhdl: - return vscode.workspace.getConfiguration().get( - linterCommand.VHDL_LINTER_CONFIG_NAME + '.diagnostor', - 'vivado' - ); - - case HdlLangID.SystemVerilog: - return vscode.workspace.getConfiguration().get( - linterCommand.SVLOG_LINTER_CONFIG_NAME + '.diagnostor', - 'vivado' - ); + // 对应配置文件的变动需要修改全局的相关变量 + vscode.workspace.onDidChangeConfiguration(async event => { + if (event.affectsConfiguration(Linter.getLinterConfigurationName(HdlLangID.Verilog))) { + await lspLinter.vlogLinterManager.updateCurrentLinterItem(client); + lspLinter.vlogLinterManager.updateStatusBar(); + } - default: - break; - } - return 'vivado'; + if (event.affectsConfiguration(Linter.getLinterConfigurationName(HdlLangID.SystemVerilog))) { + await lspLinter.svlogLinterManager.updateCurrentLinterItem(client); + lspLinter.svlogLinterManager.updateStatusBar(); + } + + if (event.affectsConfiguration(Linter.getLinterConfigurationName(HdlLangID.Vhdl))) { + await lspLinter.vhdlLinterManager.updateCurrentLinterItem(client); + lspLinter.vhdlLinterManager.updateStatusBar(); + } + }); } async function updateLinterConfiguration( client: LanguageClient, configurationName: string, - linterName: linterCommand.SupportLinterName + linterName: Linter.SupportLinterName ) { - const configuratioName = linterCommand.LinterInstallPathConfigurationNames[linterName]; + const configuratioName = Linter.getLinterInstallConfigurationName(linterName); const linterPath = vscode.workspace.getConfiguration().get(configuratioName, ''); + console.log(linterName); + await client.sendRequest(UpdateConfigurationType, { configs: [ { name: configurationName, value: linterName }, @@ -150,4 +146,4 @@ async function updateLinterConfiguration( ], configType: 'linter' }); -} \ No newline at end of file +} diff --git a/src/function/lsp-client/index.ts b/src/function/lsp-client/index.ts index f29a9fb..8d3d309 100644 --- a/src/function/lsp-client/index.ts +++ b/src/function/lsp-client/index.ts @@ -15,7 +15,7 @@ import { IProgress, LspClient, opeParam } from '../../global'; import axios, { AxiosResponse } from "axios"; import { chooseBestDownloadSource, getGiteeDownloadLink, getGithubDownloadLink, getPlatformPlatformSignature } from "./cdn"; import { hdlDir, hdlPath } from "../../hdlFs"; -import { registerConfigurationUpdater } from "./config"; +import { registerConfigurationUpdater, registerLinter } from "./config"; import { t } from "../../i18n"; function getLspServerExecutionName() { @@ -214,7 +214,10 @@ export async function activate(context: vscode.ExtensionContext, packageJson: an await client.start(); // 检测配置文件变动 - registerConfigurationUpdater(client, packageJson); + await registerConfigurationUpdater(client, packageJson); + + // 配置诊断器 + await registerLinter(client); } diff --git a/src/function/lsp/linter/base.ts b/src/function/lsp/linter/base.ts deleted file mode 100644 index 1b87c1d..0000000 --- a/src/function/lsp/linter/base.ts +++ /dev/null @@ -1,20 +0,0 @@ -import * as vscode from 'vscode'; -import { HdlLangID } from '../../../global/enum'; - -interface BaseLinter { - diagnostic: vscode.DiagnosticCollection; - lint(document: vscode.TextDocument): Promise; - remove(uri: vscode.Uri): Promise; - initialise(langID: HdlLangID): Promise; -} - -interface BaseManager { - initialise(): Promise; - updateLinter(): Promise; -} - - -export { - BaseLinter, - BaseManager -}; diff --git a/src/function/lsp/linter/command.ts b/src/function/lsp/linter/command.ts deleted file mode 100644 index 8824740..0000000 --- a/src/function/lsp/linter/command.ts +++ /dev/null @@ -1,235 +0,0 @@ -import * as vscode from 'vscode'; -import * as fs from 'fs'; - -import { vivadoLinter } from './vivado'; -import { modelsimLinter } from './modelsim'; -import { HdlLangID } from '../../../global/enum'; -import { t } from '../../../i18n'; -import { LspClient } from '../../../global'; -import { LinterStatusRequestType, UpdateConfigurationType } from '../../../global/lsp'; -import { LanguageClient } from 'vscode-languageclient/node'; - -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 = { - 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 makeLinterNamePickItem( - client: LanguageClient, - langID: HdlLangID, - linterName: SupportLinterName -): Promise { - const configuration = vscode.workspace.getConfiguration(); - const linterInstallConfigurationName = LinterInstallPathConfigurationNames[linterName]; - const linterPath = configuration.get(linterInstallConfigurationName, ''); - - 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) - } -} - - - -async function makeLinterOptions( - client: LanguageClient, - langID: HdlLangID, - linters: SupportLinterName[] -) { - const pools = []; - for (const name of linters) { - pools.push(makeLinterNamePickItem(client, langID, name)) - } - - const items = []; - for (const p of pools) { - items.push(await p); - } - return items; -} - -/** - * @description 选择 verilog 的诊断器 - */ -export async function pickVlogLinter() { - const pickWidget = vscode.window.createQuickPick(); - 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: t('info.command.loading'), - cancellable: true - }, async () => { - pickWidget.items = await makeLinterOptions(client, HdlLangID.Verilog, [ - 'iverilog', - 'modelsim', - 'verible', - 'verilator', - 'vivado' - ]); - }); - - pickWidget.onDidChangeSelection(items => { - _selectVlogLinterItem = items[0]; - }); - - 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(); - } - }); - - pickWidget.show(); -} - -/** - * @description 选择 system verilog 的诊断器 - */ -export async function pickSvlogLinter() { - const pickWidget = vscode.window.createQuickPick(); - 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: t("info.command.loading"), - cancellable: true - }, async () => { - pickWidget.items = await makeLinterOptions(client, HdlLangID.SystemVerilog, [ - 'modelsim', - 'verible', - 'verilator', - 'vivado' - ]); - }); - - pickWidget.onDidChangeSelection(items => { - _selectSvlogLinterItem = items[0]; - }); - - 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(); - } - }); - - pickWidget.show(); -} - -/** - * @description 选择 vhdl 的诊断器 - */ -export async function pickVhdlLinter() { - const pickWidget = vscode.window.createQuickPick(); - 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: t("info.command.loading"), - cancellable: true - }, async () => { - pickWidget.items = await makeLinterOptions(client, HdlLangID.Vhdl, [ - 'modelsim', - 'vivado' - ]); - }); - - pickWidget.onDidChangeSelection(items => { - _selectVhdlLinterItem = items[0]; - }); - - 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(); -} diff --git a/src/function/lsp/linter/common.ts b/src/function/lsp/linter/common.ts new file mode 100644 index 0000000..7c42ef9 --- /dev/null +++ b/src/function/lsp/linter/common.ts @@ -0,0 +1,112 @@ +import * as vscode from 'vscode'; +import * as fs from 'fs'; + +import { vivadoLinter } from './vivado'; +import { modelsimLinter } from './modelsim'; +import { HdlLangID } from '../../../global/enum'; +import { t } from '../../../i18n'; +import { LspClient } from '../../../global'; +import { LinterStatusRequestType, UpdateConfigurationType } from '../../../global/lsp'; +import { LanguageClient } from 'vscode-languageclient/node'; + +export interface LinterItem extends vscode.QuickPickItem { + name: SupportLinterName + linterPath: string + available: boolean +} + +export let _selectVlogLinterItem: LinterItem | undefined = undefined; +export let _selectSvlogLinterItem: LinterItem | undefined = undefined; +export let _selectVhdlLinterItem: LinterItem | undefined = undefined; + +// 第三方诊断器路径的相关配置 +// 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'; + +/** + * @description 获取指向【当前的 linter 的名字】的配置的名字,比如 `digital-ide.function.lsp.linter.verilog.diagnostor` + */ +export function getLinterConfigurationName(langID: HdlLangID): string { + return `digital-ide.function.lsp.linter.${langID}.diagnostor`; +} + +/** + * @description 获取当前的 linter 的名字,比如 `vivado` + */ +export function getLinterName(langID: HdlLangID): SupportLinterName { + const linterConfigurationName = getLinterConfigurationName(langID); + return vscode.workspace.getConfiguration().get(linterConfigurationName, 'vivado'); +} + +export function updateLinterConfigurationName(langID: HdlLangID, linterName: SupportLinterName) { + const sectionName = `digital-ide.function.lsp.linter.${langID}`; + const linterConfiguration = vscode.workspace.getConfiguration(sectionName); + linterConfiguration.update('diagnostor', linterName, vscode.ConfigurationTarget.Global); +} + +export function getLinterInstallConfigurationName(linterName: SupportLinterName): string { + return `digital-ide.prj.${linterName}.install.path`; +} + +/** + * @description 生成 PickItem,这个过程中会对当前 linterName 的有效性进行校验 + * @param client + * @param langID + * @param linterName + * @returns + */ +export async function makeLinterNamePickItem( + client: LanguageClient, + langID: HdlLangID, + linterName: SupportLinterName +): Promise { + const configuration = vscode.workspace.getConfiguration(); + const linterInstallConfigurationName = getLinterInstallConfigurationName(linterName); + const linterPath = configuration.get(linterInstallConfigurationName, ''); + + const linterStatus = await client.sendRequest(LinterStatusRequestType, { + languageId: langID, + linterName, + linterPath + }); + + return { + label: '$(getting-started-beginner) ' + linterName, + name: linterName, + linterPath, + available: linterStatus.available, + description: linterStatus.toolName, + detail: t('info.common.some-is-ready', linterStatus.invokeName) + } +} + +export async function makeLinterOptions( + client: LanguageClient, + langID: HdlLangID, + linters: SupportLinterName[] +) { + const pools = []; + for (const name of linters) { + pools.push(makeLinterNamePickItem(client, langID, name)) + } + + const items = []; + for (const p of pools) { + items.push(await p); + } + return items; +} + +export enum LinterMode { + Full = 'full', + Single = 'single', + Shutdown = 'shutdown' +} + +export function getLinterMode(): LinterMode { + return vscode.workspace.getConfiguration().get('digital-ide.function.lsp.linter.linter-mode', LinterMode.Full); +} \ No newline at end of file diff --git a/src/function/lsp/linter/default.ts b/src/function/lsp/linter/default.ts deleted file mode 100644 index d9556cf..0000000 --- a/src/function/lsp/linter/default.ts +++ /dev/null @@ -1,166 +0,0 @@ -import * as vscode from 'vscode'; -import { isVerilogFile, isVhdlFile } from '../../../hdlFs/file'; -import { All, Position } from '../../../hdlParser/common'; -import { BaseLinter } from './base'; -import { LspOutput, ReportType } from '../../../global'; - - -class DefaultVlogLinter implements BaseLinter { - diagnostic: vscode.DiagnosticCollection; - constructor() { - this.diagnostic = vscode.languages.createDiagnosticCollection('Digital-IDE Default Linter'); - } - - async lint(document: vscode.TextDocument): Promise { - const filePath = document.fileName; - // const vlogAll = await hdlSymbolStorage.getSymbol(filePath); - // // console.log('lint all finish'); - - // if (vlogAll) { - // const diagnostics = this.provideDiagnostics(document, vlogAll); - // this.diagnostic.set(document.uri, diagnostics); - // } - } - - private provideDiagnostics(document: vscode.TextDocument, all: All): vscode.Diagnostic[] { - const diagnostics: vscode.Diagnostic[] = []; - if (all.error && all.error.length > 0) { - for (const hdlError of all.error) { - LspOutput.report(` line: ${hdlError.range.line}, info: ${hdlError.message}`, { - level: ReportType.Run - }); - const syntaxInfo = hdlError.message.replace(/\\r\\n/g, '\n'); - const range = this.makeCorrectRange(document, hdlError.range); - const diag = new vscode.Diagnostic(range, syntaxInfo, hdlError.severity); - diag.source = hdlError.source; - diagnostics.push(diag); - } - } - return diagnostics; - } - - private makeCorrectRange(document: vscode.TextDocument, range: Position): vscode.Range { - range.line --; - if (range.character === 0 && range.line > 0) { - range.line --; - } - - while (range.line > 0) { - const lineContent = document.lineAt(range.line).text; - if (lineContent.trim().length > 0) { - break; - } else { - range.line --; - } - } - - const currentLine = document.lineAt(range.line).text; - if (range.character === 0 && currentLine.trim().length > 0) { - range.character = currentLine.trimEnd().length; - } - - const position = new vscode.Position(range.line, range.character); - const wordRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/); - if (wordRange) { - return wordRange; - } else { - const errorEnd = new vscode.Position(range.line, range.character + 1); - const errorRange = new vscode.Range(position, errorEnd); - return errorRange; - } - } - - async remove(uri: vscode.Uri) { - this.diagnostic.delete(uri); - } - - public async initialise() { - // move code to outer layer - return true; - } -} - -class DefaultVhdlLinter implements BaseLinter { - diagnostic: vscode.DiagnosticCollection; - constructor() { - this.diagnostic = vscode.languages.createDiagnosticCollection(); - } - - async lint(document: vscode.TextDocument): Promise { - const filePath = document.fileName; - // const vhdlAll = await hdlSymbolStorage.getSymbol(filePath); - // // console.log('lint all finish'); - - // if (vhdlAll) { - // const diagnostics = this.provideDiagnostics(document, vhdlAll); - // this.diagnostic.set(document.uri, diagnostics); - // } - } - - private provideDiagnostics(document: vscode.TextDocument, all: All): vscode.Diagnostic[] { - const diagnostics: vscode.Diagnostic[] = []; - if (all.error && all.error.length > 0) { - for (const hdlError of all.error) { - LspOutput.report(` line: ${hdlError.range.line}, info: ${hdlError.message}`, { - level: ReportType.Run - }); - - const range = this.makeCorrectRange(document, hdlError.range); - const diag = new vscode.Diagnostic(range, hdlError.message, hdlError.severity); - diag.source = hdlError.source; - diagnostics.push(diag); - } - } - return diagnostics; - } - - private makeCorrectRange(document: vscode.TextDocument, range: Position): vscode.Range { - range.line --; - if (range.character === 0 && range.line > 0) { - range.line --; - } - - while (range.line > 0) { - const lineContent = document.lineAt(range.line).text; - if (lineContent.trim().length > 0) { - break; - } else { - range.line --; - } - } - - const currentLine = document.lineAt(range.line).text; - if (range.character === 0 && currentLine.trim().length > 0) { - range.character = currentLine.trimEnd().length; - } - - const position = new vscode.Position(range.line, range.character); - const wordRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/); - if (wordRange) { - return wordRange; - } else { - const errorEnd = new vscode.Position(range.line, range.character + 1); - const errorRange = new vscode.Range(position, errorEnd); - return errorRange; - } - } - - async remove(uri: vscode.Uri) { - this.diagnostic.delete(uri); - } - - public async initialise() { - // move code to outer layer - return true; - } -} - -const defaultVlogLinter = new DefaultVlogLinter(); -const defaultVhdlLinter = new DefaultVhdlLinter(); - -export { - defaultVlogLinter, - defaultVhdlLinter, - DefaultVlogLinter, - DefaultVhdlLinter -}; diff --git a/src/function/lsp/linter/index.ts b/src/function/lsp/linter/index.ts index 2c70be1..d538760 100644 --- a/src/function/lsp/linter/index.ts +++ b/src/function/lsp/linter/index.ts @@ -1,14 +1,11 @@ -import { vlogLinterManager } from './vlog'; -import { vhdlLinterManager } from './vhdl'; -import { svlogLinterManager } from './svlog'; - -import { pickVlogLinter, pickVhdlLinter, pickSvlogLinter } from './command'; +import { + vlogLinterManager, + vhdlLinterManager, + svlogLinterManager +} from './manager'; export { vlogLinterManager, vhdlLinterManager, - svlogLinterManager, - pickVlogLinter, - pickVhdlLinter, - pickSvlogLinter, + svlogLinterManager }; \ No newline at end of file diff --git a/src/function/lsp/linter/manager.ts b/src/function/lsp/linter/manager.ts new file mode 100644 index 0000000..9e25a34 --- /dev/null +++ b/src/function/lsp/linter/manager.ts @@ -0,0 +1,261 @@ +import * as vscode from 'vscode'; +import { LspClient, LspOutput, ReportType } from '../../../global'; +import { HdlLangID } from '../../../global/enum'; +import { hdlFile, hdlPath } from '../../../hdlFs'; +import { t } from '../../../i18n'; +import { getLinterConfigurationName, getLinterInstallConfigurationName, getLinterMode, getLinterName, LinterItem, LinterMode, makeLinterNamePickItem, makeLinterOptions, SupportLinterName, updateLinterConfigurationName } from './common'; +import { LinterStatusRequestType, UpdateConfigurationType } from '../../../global/lsp'; +import { LanguageClient } from 'vscode-languageclient/node'; + +class LinterManager { + /** + * @description 当前诊断器管理者绑定的语言 + */ + langID: HdlLangID; + + /** + * @description 描述当前诊断器管理者支持哪些第三方诊断器 + */ + supportLinters: SupportLinterName[]; + + /** + * @description 内部变量,用来存储用户选择的诊断器,也是 picker 操作结果的绑定值 + */ + currentLinterItem: LinterItem | undefined; + + /** + * @description 诊断器管理者绑定的右下角的 status item + */ + statusBarItem: vscode.StatusBarItem; + + /** + * @description 用户保证 start 函数的必要操作为幂等的 + */ + started: boolean; + + /** + * @description 绑定的 lsp,当 started 为 true 时,该值一定不为 undefined + */ + lspClient: LanguageClient | undefined; + + constructor(langID: HdlLangID, supportLinters: SupportLinterName[]) { + this.langID = langID; + this.supportLinters = supportLinters; + this.started = false; + this.currentLinterItem = undefined; + this.lspClient = undefined; + + // 在窗体右下角创建一个状态栏,用于显示目前激活的诊断器 + this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); + this.statusBarItem.command = this.getLinterPickCommand(); + + // 对切换时间进行监听,如果不是目前的语言,则隐藏 + this.registerActiveTextEditorChangeEvent(langID); + } + + /** + * @description 根据 语言 或者对应选择诊断器的 command + * @param langID + * @returns + */ + public getLinterPickCommand() { + switch (this.langID) { + case HdlLangID.Verilog: + return 'digital-ide.lsp.vlog.linter.pick'; + case HdlLangID.SystemVerilog: + return 'digital-ide.lsp.svlog.linter.pick'; + case HdlLangID.Vhdl: + return 'digital-ide.lsp.vhdl.linter.pick'; + default: + break; + } + return 'digital-ide.lsp.vlog.linter.pick'; + } + + /** + * @description 手动更新 currentLinterItem,仅在外部更新 status bar 时使用 + * @param client + */ + public async updateCurrentLinterItem(client?: LanguageClient) { + client = client ? client : this.lspClient; + if (client) { + const linterName = getLinterName(this.langID); + this.currentLinterItem = await makeLinterNamePickItem(client, this.langID, linterName); + } + } + + /** + * @description 启动诊断器 + * @returns + */ + async start(client: LanguageClient): Promise { + // 根据配置选择对应的诊断器 + await this.updateCurrentLinterItem(client); + + // TODO: 根据当前的诊断模式进行选择 + + + // 注册内部命令 + if (!this.started) { + const pickerCommand = this.getLinterPickCommand(); + vscode.commands.registerCommand(pickerCommand, () => { + this.pickLinter(); + }); + } + + // 保证幂等 + this.started = true; + this.lspClient = client; + + // 如果当前窗口语言为绑定语言,则显示 bar;否则,隐藏它 + const editor = vscode.window.activeTextEditor; + if (editor && this.langID === hdlFile.getLanguageId(editor.document.fileName)) { + this.updateStatusBar(); + } else { + this.statusBarItem.hide(); + } + + LspOutput.report(t('info.linter.finish-init', "verilog", this.currentLinterItem?.name || 'unknown'), { + level: ReportType.Launch + }); + } + + /** + * @description 刷新当前工作区所有文件的 linter 状态。仅仅在初始化和更新配置文件时需要使用。 + */ + public async refreshWorkspaceLinterResult(linterMode: LinterMode) { + switch (linterMode) { + case LinterMode.Full: + + break; + case LinterMode.Single: + + break; + case LinterMode.Shutdown: + + break; + default: + break; + } + } + + /** + * @description 更新右下角 status bar 的状态 + */ + public updateStatusBar() { + const statusBarItem = this.statusBarItem; + const currentLinterItem = this.currentLinterItem; + if (currentLinterItem) { + if (currentLinterItem.available) { + statusBarItem.text = `$(getting-started-beginner) Linter(${currentLinterItem.name})`; + } else { + statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground'); + statusBarItem.tooltip = t('error.linter.status-bar.tooltip', currentLinterItem.name); + statusBarItem.text = `$(extensions-warning-message) Linter(${currentLinterItem.name})`; + LspOutput.report(t('error.linter.status-bar.tooltip', currentLinterItem.name), { + level: ReportType.Error + }); + } + statusBarItem.show(); + } + } + + private registerActiveTextEditorChangeEvent(langID: HdlLangID) { + vscode.window.onDidChangeActiveTextEditor(editor => { + if (!editor) { + return; + } + const currentFileName = hdlPath.toSlash(editor.document.fileName); + const currentID = hdlFile.getLanguageId(currentFileName); + if (langID === currentID) { + this.updateStatusBar(); + } else { + this.statusBarItem.hide(); + } + }); + } + + private makePickTitle() { + switch (this.langID) { + case HdlLangID.Verilog: + return t("info.linter.pick-for-verilog"); + case HdlLangID.SystemVerilog: + return t("info.linter.pick-for-system-verilog"); + case HdlLangID.Vhdl: + return t("info.linter.pick-for-vhdl"); + default: + return t("info.linter.pick-for-verilog"); + } + } + + /** + * @description 为当前的语言选择一个诊断器 + */ + public async pickLinter() { + const pickWidget = vscode.window.createQuickPick(); + pickWidget.placeholder = this.makePickTitle(); + pickWidget.canSelectMany = false; + + const client = this.lspClient; + if (!client) { + return; + } + + // 制作 pick 的选项卡,选项卡的每一个子项目都经过检查 + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: t('info.command.loading'), + cancellable: true + }, async () => { + pickWidget.items = await makeLinterOptions(client, this.langID, this.supportLinters); + }); + + // 激活当前的 linter name 对应的选项卡 + const currentLinterName = getLinterName(this.langID); + const activeItems = pickWidget.items.filter(item => item.name === currentLinterName); + pickWidget.activeItems = activeItems; + + pickWidget.onDidChangeSelection(items => { + this.currentLinterItem = items[0]; + }); + + pickWidget.onDidAccept(async () => { + if (this.currentLinterItem) { + // 更新 vscode 配置文件 + updateLinterConfigurationName(this.langID, this.currentLinterItem.name); + // 更新后端 + await client.sendRequest(UpdateConfigurationType, { + configs: [ + { name: getLinterConfigurationName(this.langID), value: this.currentLinterItem.name }, + { name: 'path', value: this.currentLinterItem.linterPath } + ], + configType: 'linter' + }); + // 更新 status bar + this.updateStatusBar(); + + pickWidget.hide(); + } + }); + + pickWidget.show(); + } +} + +export const vlogLinterManager = new LinterManager(HdlLangID.Verilog, [ + 'iverilog', + 'modelsim', + 'verible', + 'verilator', + 'vivado' +]); +export const vhdlLinterManager = new LinterManager(HdlLangID.Vhdl, [ + 'modelsim', + 'vivado' +]); +export const svlogLinterManager = new LinterManager(HdlLangID.SystemVerilog, [ + 'modelsim', + 'verible', + 'verilator', + 'vivado' +]); \ No newline at end of file diff --git a/src/function/lsp/linter/modelsim.ts b/src/function/lsp/linter/modelsim.ts index 91cfb8f..a973660 100644 --- a/src/function/lsp/linter/modelsim.ts +++ b/src/function/lsp/linter/modelsim.ts @@ -4,10 +4,9 @@ import * as fs from 'fs'; import { LspOutput, ReportType, opeParam } from "../../../global"; import { hdlFile, hdlPath } from "../../../hdlFs"; import { easyExec } from "../../../global/util"; -import { BaseLinter } from "./base"; import { HdlLangID } from "../../../global/enum"; -class ModelsimLinter implements BaseLinter { +class ModelsimLinter { diagnostic: vscode.DiagnosticCollection; executableFileMap: Map = new Map(); executableInvokeNameMap: Map = new Map(); diff --git a/src/function/lsp/linter/svlog.ts b/src/function/lsp/linter/svlog.ts deleted file mode 100644 index 4ff1307..0000000 --- a/src/function/lsp/linter/svlog.ts +++ /dev/null @@ -1,202 +0,0 @@ -import * as vscode from 'vscode'; -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'; -import { hdlFile, hdlPath } from '../../../hdlFs'; - -class SvlogLinterManager implements BaseManager { - currentLinter: BaseLinter | undefined; - activateLinterName: string; - statusBarItem: vscode.StatusBarItem; - initialized: boolean; - - constructor() { - this.activateLinterName = 'default'; - this.initialized = false; - - // make a status bar for rendering - this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); - this.statusBarItem.command = 'digital-ide.lsp.svlog.linter.pick'; - - // when changing file, hide if langID is not verilog - vscode.window.onDidChangeActiveTextEditor(editor => { - if (!editor) { - return; - } - const currentFileName = hdlPath.toSlash(editor.document.fileName); - - if (hdlFile.isSystemVerilogFile(currentFileName)) { - this.statusBarItem.show(); - } else { - this.statusBarItem.hide(); - } - }); - - // update when user's config is changed - vscode.workspace.onDidChangeConfiguration(() => { - this.updateLinter(); - }); - } - - async initialise(): Promise { - const success = await this.updateLinter(); - - if (!success) { - return; - } - - this.initialized = true; - - for (const doc of vscode.workspace.textDocuments) { - const fileName = hdlPath.toSlash(doc.fileName); - if (hdlFile.isSystemVerilogFile(fileName)) { - await this.lint(doc); - } - } - LspOutput.report(' finish initialization of svlog linter. Linter name: ' + this.activateLinterName, { - level: ReportType.Launch - }); - - // hide it if current window is not verilog - const editor = vscode.window.activeTextEditor; - if (editor && hdlFile.isSystemVerilogFile(editor.document.fileName)) { - this.statusBarItem.show(); - } else { - this.statusBarItem.hide(); - } - } - - async lint(document: vscode.TextDocument) { - this.currentLinter?.remove(document.uri); - await this.currentLinter?.lint(document); - } - - async remove(uri: vscode.Uri): Promise { - this.currentLinter?.remove(uri); - } - - public getUserDiagnostorSelection() { - const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.svlog'); - const diagnostor = vlogLspConfig.get('diagnostor', 'xxx'); - return diagnostor; - } - - public async updateLinter(): Promise { - const diagnostorName = this.getUserDiagnostorSelection(); - - const lastDiagnostorName = this.activateLinterName; - const lastDiagnostor = this.currentLinter; - - if (this.initialized && diagnostorName === lastDiagnostorName) { - // no need for update - return true; - } - LspOutput.report(` detect linter setting changes, switch from ${lastDiagnostorName} to ${diagnostorName}.`, { - level: ReportType.Launch - }); - - let launch = false; - switch (diagnostorName) { - case 'vivado': launch = await this.activateVivado(); break; - case 'modelsim': launch = await this.activateModelsim(); break; - case 'default': launch = await this.activateDefault(); break; - default: launch = await this.activateDefault(); break; - } - - for (const doc of vscode.workspace.textDocuments) { - const fileName = hdlPath.toSlash(doc.fileName); - if (hdlFile.isSystemVerilogFile(fileName)) { - lastDiagnostor?.remove(doc.uri); - await this.lint(doc); - } - } - - return launch; - } - - public async activateVivado(): Promise { - const selectedLinter = vivadoLinter; - let launch = true; - - launch = await selectedLinter.initialise(HdlLangID.SystemVerilog); - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)'; - - LspOutput.report(' vivado linter has been activated'); - } else { - this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground'); - this.statusBarItem.tooltip = 'Fail to launch vivado linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(vivado)'; - - LspOutput.report(' Fail to launch vivado linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'vivado'; - this.statusBarItem.show(); - - return launch; - } - - public async activateModelsim(): Promise { - const selectedLinter = modelsimLinter; - let launch = true; - - launch = await selectedLinter.initialise(HdlLangID.SystemVerilog); - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)'; - - LspOutput.report(' modelsim linter has been activated'); - } else { - this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground'); - this.statusBarItem.tooltip = 'Fail to launch modelsim linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(modelsim)'; - - LspOutput.report(' Fail to launch modelsim linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'modelsim'; - this.statusBarItem.show(); - - return launch; - } - - public async activateDefault(): Promise { - const selectedLinter = defaultVlogLinter; - let launch = true; - - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(default)'; - - LspOutput.report(' default build-in linter has been activated'); - } else { - this.statusBarItem.backgroundColor = undefined; - this.statusBarItem.tooltip = 'Fail to launch default linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(default)'; - - LspOutput.report(' Fail to launch default linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'default'; - this.statusBarItem.show(); - - return launch; - } -} - -const svlogLinterManager = new SvlogLinterManager(); - -export { - svlogLinterManager -}; diff --git a/src/function/lsp/linter/verilator.ts b/src/function/lsp/linter/verilator.ts index 84a32eb..06668b0 100644 --- a/src/function/lsp/linter/verilator.ts +++ b/src/function/lsp/linter/verilator.ts @@ -4,12 +4,11 @@ import * as fs from 'fs'; import { LspOutput, ReportType, opeParam } from "../../../global"; import { hdlFile, hdlPath } from "../../../hdlFs"; import { easyExec } from "../../../global/util"; -import { BaseLinter } from "./base"; import { HdlLangID } from "../../../global/enum"; type Path = string; -class VerilatorLinter implements BaseLinter { +class VerilatorLinter { diagnostic: vscode.DiagnosticCollection; executableFileMap: Map = new Map(); executableInvokeNameMap: Map = new Map(); diff --git a/src/function/lsp/linter/vhdl.ts b/src/function/lsp/linter/vhdl.ts deleted file mode 100644 index 612a2b5..0000000 --- a/src/function/lsp/linter/vhdl.ts +++ /dev/null @@ -1,202 +0,0 @@ -import * as vscode from 'vscode'; -import { LspOutput, ReportType } from '../../../global'; -import { HdlLangID } from '../../../global/enum'; -import { BaseLinter, BaseManager } from './base'; -import { defaultVhdlLinter } from './default'; -import { modelsimLinter } from './modelsim'; -import { vivadoLinter } from './vivado'; -import { hdlFile, hdlPath } from '../../../hdlFs'; - -class VhdlLinterManager implements BaseManager { - currentLinter: BaseLinter | undefined; - activateLinterName: string; - statusBarItem: vscode.StatusBarItem; - initialized: boolean; - - constructor() { - this.activateLinterName = 'default'; - this.initialized = false; - - // make a status bar for rendering - this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); - this.statusBarItem.command = 'digital-ide.lsp.vhdl.linter.pick'; - - // when changing file, hide if langID is not vhdl - vscode.window.onDidChangeActiveTextEditor(editor => { - if (!editor) { - return; - } - const currentFileName = hdlPath.toSlash(editor.document.fileName); - - if (hdlFile.isVhdlFile(currentFileName)) { - this.statusBarItem.show(); - } else { - this.statusBarItem.hide(); - } - }); - - // update when user's config is changed - vscode.workspace.onDidChangeConfiguration(() => { - this.updateLinter(); - }); - } - - async initialise(): Promise { - const success = await this.updateLinter(); - - if (!success) { - return; - } - - this.initialized = true; - - for (const doc of vscode.workspace.textDocuments) { - const fileName = hdlPath.toSlash(doc.fileName); - if (hdlFile.isVhdlFile(fileName)) { - await this.lint(doc); - } - } - LspOutput.report(' finish initialization of vhdl linter. Linter name: ' + this.activateLinterName, { - level: ReportType.Launch - }); - - // hide it if current window is not vhdl - const editor = vscode.window.activeTextEditor; - if (editor && hdlFile.isVhdlFile(editor.document.fileName)) { - this.statusBarItem.show(); - } else { - this.statusBarItem.hide(); - } - } - - async lint(document: vscode.TextDocument) { - this.currentLinter?.remove(document.uri); - await this.currentLinter?.lint(document); - } - - async remove(uri: vscode.Uri): Promise { - this.currentLinter?.remove(uri); - } - - public getUserDiagnostorSelection() { - const vhdlLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vhdl'); - const diagnostor = vhdlLspConfig.get('diagnostor', 'xxx'); - return diagnostor; - } - - public async updateLinter(): Promise { - const diagnostorName = this.getUserDiagnostorSelection(); - - const lastDiagnostorName = this.activateLinterName; - const lastDiagnostor = this.currentLinter; - - if (this.initialized && diagnostorName === lastDiagnostorName) { - // no need for update - return true; - } - LspOutput.report(` detect linter setting changes, switch from ${lastDiagnostorName} to ${diagnostorName}.`, { - level: ReportType.Launch - }); - - let launch = false; - switch (diagnostorName) { - case 'vivado': launch = await this.activateVivado(); break; - case 'modelsim': launch = await this.activateModelsim(); break; - case 'default': launch = await this.activateDefault(); break; - default: launch = await this.activateDefault(); break; - } - - for (const doc of vscode.workspace.textDocuments) { - const fileName = hdlPath.toSlash(doc.fileName); - if (hdlFile.isVhdlFile(fileName)) { - lastDiagnostor?.remove(doc.uri); - await this.lint(doc); - } - } - - return launch; - } - - public async activateVivado(): Promise { - const selectedLinter = vivadoLinter; - let launch = true; - - launch = await selectedLinter.initialise(HdlLangID.Vhdl); - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)'; - - LspOutput.report(' vivado linter has been activated'); - } else { - this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground'); - this.statusBarItem.tooltip = 'Fail to launch vivado linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(vivado)'; - - LspOutput.report(' Fail to launch vivado linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'vivado'; - this.statusBarItem.show(); - - return launch; - } - - public async activateModelsim(): Promise { - const selectedLinter = modelsimLinter; - let launch = true; - - launch = await selectedLinter.initialise(HdlLangID.Vhdl); - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)'; - - LspOutput.report(' modelsim linter has been activated'); - } else { - this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground'); - this.statusBarItem.tooltip = 'Fail to launch modelsim linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(modelsim)'; - - LspOutput.report(' Fail to launch modelsim linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'modelsim'; - this.statusBarItem.show(); - - return launch; - } - - public async activateDefault(): Promise { - const selectedLinter = defaultVhdlLinter; - let launch = true; - - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(default)'; - - LspOutput.report(' default build-in linter has been activated'); - } else { - this.statusBarItem.backgroundColor = undefined; - this.statusBarItem.tooltip = 'Fail to launch default linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(default)'; - - LspOutput.report(' Fail to launch default linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'default'; - this.statusBarItem.show(); - - return launch; - } -} - -const vhdlLinterManager = new VhdlLinterManager(); - -export { - vhdlLinterManager -}; diff --git a/src/function/lsp/linter/vivado.ts b/src/function/lsp/linter/vivado.ts index ae357f6..157679d 100644 --- a/src/function/lsp/linter/vivado.ts +++ b/src/function/lsp/linter/vivado.ts @@ -4,12 +4,11 @@ import * as fs from 'fs'; import { LspOutput, ReportType, opeParam } from "../../../global"; import { hdlFile, hdlPath } from "../../../hdlFs"; import { easyExec } from "../../../global/util"; -import { BaseLinter } from "./base"; import { HdlLangID } from "../../../global/enum"; type Path = string; -class VivadoLinter implements BaseLinter { +class VivadoLinter { diagnostic: vscode.DiagnosticCollection; executableFileMap: Map = new Map(); executableInvokeNameMap: Map = new Map(); diff --git a/src/function/lsp/linter/vlog.ts b/src/function/lsp/linter/vlog.ts deleted file mode 100644 index 18500cb..0000000 --- a/src/function/lsp/linter/vlog.ts +++ /dev/null @@ -1,202 +0,0 @@ -import * as vscode from 'vscode'; -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'; -import { hdlFile, hdlPath } from '../../../hdlFs'; - -class VlogLinterManager implements BaseManager { - currentLinter: BaseLinter | undefined; - activateLinterName: string; - statusBarItem: vscode.StatusBarItem; - initialized: boolean; - - constructor() { - this.activateLinterName = 'default'; - this.initialized = false; - - // make a status bar for rendering - this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); - this.statusBarItem.command = 'digital-ide.lsp.vlog.linter.pick'; - - // when changing file, hide if langID is not verilog - vscode.window.onDidChangeActiveTextEditor(editor => { - if (!editor) { - return; - } - const currentFileName = hdlPath.toSlash(editor.document.fileName); - - if (hdlFile.isVerilogFile(currentFileName)) { - this.statusBarItem.show(); - } else { - this.statusBarItem.hide(); - } - }); - - // update when user's config is changed - vscode.workspace.onDidChangeConfiguration(() => { - this.updateLinter(); - }); - } - - async initialise(): Promise { - const success = await this.updateLinter(); - - if (!success) { - return; - } - - this.initialized = true; - - for (const doc of vscode.workspace.textDocuments) { - const fileName = hdlPath.toSlash(doc.fileName); - if (hdlFile.isVerilogFile(fileName)) { - await this.lint(doc); - } - } - LspOutput.report(' finish initialization of vlog linter. Linter name: ' + this.activateLinterName, { - level: ReportType.Launch - }); - - // hide it if current window is not verilog - const editor = vscode.window.activeTextEditor; - if (editor && hdlFile.isVerilogFile(editor.document.fileName)) { - this.statusBarItem.show(); - } else { - this.statusBarItem.hide(); - } - } - - async lint(document: vscode.TextDocument) { - this.currentLinter?.remove(document.uri); - await this.currentLinter?.lint(document); - } - - async remove(uri: vscode.Uri): Promise { - this.currentLinter?.remove(uri); - } - - public getUserDiagnostorSelection() { - const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vlog'); - const diagnostor = vlogLspConfig.get('diagnostor', 'xxx'); - return diagnostor; - } - - public async updateLinter(): Promise { - const diagnostorName = this.getUserDiagnostorSelection(); - - const lastDiagnostorName = this.activateLinterName; - const lastDiagnostor = this.currentLinter; - - if (this.initialized && diagnostorName === lastDiagnostorName) { - // no need for update - return true; - } - LspOutput.report(` detect linter setting changes, switch from ${lastDiagnostorName} to ${diagnostorName}.`, { - level: ReportType.Launch - }); - - let launch = false; - switch (diagnostorName) { - case 'vivado': launch = await this.activateVivado(); break; - case 'modelsim': launch = await this.activateModelsim(); break; - case 'default': launch = await this.activateDefault(); break; - default: launch = await this.activateDefault(); break; - } - - for (const doc of vscode.workspace.textDocuments) { - const fileName = hdlPath.toSlash(doc.fileName); - if (hdlFile.isVerilogFile(fileName)) { - lastDiagnostor?.remove(doc.uri); - await this.lint(doc); - } - } - - return launch; - } - - public async activateVivado(): Promise { - const selectedLinter = vivadoLinter; - let launch = true; - - launch = await selectedLinter.initialise(HdlLangID.Verilog); - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)'; - - LspOutput.report(' vivado linter has been activated'); - } else { - this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground'); - this.statusBarItem.tooltip = 'Fail to launch vivado linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(vivado)'; - - LspOutput.report(' Fail to launch vivado linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'vivado'; - this.statusBarItem.show(); - - return launch; - } - - public async activateModelsim(): Promise { - const selectedLinter = modelsimLinter; - let launch = true; - - launch = await selectedLinter.initialise(HdlLangID.Verilog); - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)'; - - LspOutput.report(' modelsim linter has been activated'); - } else { - this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground'); - this.statusBarItem.tooltip = 'Fail to launch modelsim linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(modelsim)'; - - LspOutput.report(' Fail to launch modelsim linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'modelsim'; - this.statusBarItem.show(); - - return launch; - } - - public async activateDefault(): Promise { - const selectedLinter = defaultVlogLinter; - let launch = true; - - if (launch) { - this.statusBarItem.text = '$(getting-started-beginner) Linter(default)'; - - LspOutput.report(' default build-in linter has been activated'); - } else { - this.statusBarItem.backgroundColor = undefined; - this.statusBarItem.tooltip = 'Fail to launch default linter'; - this.statusBarItem.text = '$(extensions-warning-message) Linter(default)'; - - LspOutput.report(' Fail to launch default linter', { - level: ReportType.Error - }); - } - - this.currentLinter = selectedLinter; - this.activateLinterName = 'default'; - this.statusBarItem.show(); - - return launch; - } -} - -const vlogLinterManager = new VlogLinterManager(); - -export { - vlogLinterManager -}; diff --git a/src/hdlParser/core.ts b/src/hdlParser/core.ts index 7d169ab..82dcf36 100644 --- a/src/hdlParser/core.ts +++ b/src/hdlParser/core.ts @@ -863,7 +863,6 @@ class HdlModule { const instances = new Set(); // 获取自身的 for (const inst of this.nameToInstances.values()) { - console.log(inst); instances.add(inst); // 递归获取 inst 的 if (inst.module) { @@ -1148,8 +1147,6 @@ export class HdlFile { // add to global hdlParam hdlParam.setHdlFile(this); - console.log(modules); - // make nameToModule this.nameToModule = new Map(); for (const rawHdlModule of modules) { diff --git a/src/monitor/hdl.ts b/src/monitor/hdl.ts index 712fe8d..5f6b023 100644 --- a/src/monitor/hdl.ts +++ b/src/monitor/hdl.ts @@ -164,17 +164,6 @@ export class HdlAction extends BaseAction { // 下一个版本丢弃,完全由后端承担这部分功能 async updateLinter(path: string) { - const uri = vscode.Uri.file(path); - const document = await vscode.workspace.openTextDocument(uri); - const langID = hdlFile.getLanguageId(path); - - if (langID === HdlLangID.Verilog) { - vlogLinterManager.lint(document); - } else if (langID === HdlLangID.Vhdl) { - vhdlLinterManager.lint(document); - } else if (langID === HdlLangID.SystemVerilog) { - svlogLinterManager.lint(document); - } } }