完成诊断器多端配置同步

This commit is contained in:
锦恢 2024-12-07 23:39:10 +08:00
parent 11b5349582
commit 8046a1eb00
28 changed files with 550 additions and 1209 deletions

View File

@ -89,5 +89,7 @@
"info.linter.vivado.xvlog-name": "Vivado-Diagnosetools", "info.linter.vivado.xvlog-name": "Vivado-Diagnosetools",
"info.common.some-is-ready": "{0} ist bereit", "info.common.some-is-ready": "{0} ist bereit",
"info.common.not-available": "{0} ist derzeit nicht verfügbar", "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"
} }

View File

@ -89,5 +89,7 @@
"info.linter.vivado.xvlog-name": "Vivado diagnostic tools", "info.linter.vivado.xvlog-name": "Vivado diagnostic tools",
"info.common.some-is-ready": "{0} is ready", "info.common.some-is-ready": "{0} is ready",
"info.common.not-available": "{0} is currently unavailable", "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"
} }

View File

@ -89,5 +89,7 @@
"info.linter.vivado.xvlog-name": "Vivado診断ツール", "info.linter.vivado.xvlog-name": "Vivado診断ツール",
"info.common.some-is-ready": "{0} は準備ができています", "info.common.some-is-ready": "{0} は準備ができています",
"info.common.not-available": "{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} 診断機能を取得できません"
} }

View File

@ -89,5 +89,7 @@
"info.linter.vivado.xvlog-name": "vivado 诊断工具", "info.linter.vivado.xvlog-name": "vivado 诊断工具",
"info.common.some-is-ready": "{0} 已经准备就绪", "info.common.some-is-ready": "{0} 已经准备就绪",
"info.common.not-available": "{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} 诊断器"
} }

View File

@ -89,5 +89,7 @@
"info.linter.vivado.xvlog-name": "Vivado診斷工具", "info.linter.vivado.xvlog-name": "Vivado診斷工具",
"info.common.some-is-ready": "{0} 已經準備就緒", "info.common.some-is-ready": "{0} 已經準備就緒",
"info.common.not-available": "{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} 診斷器"
} }

View File

@ -235,68 +235,70 @@
"type": "boolean", "type": "boolean",
"default": true "default": true
}, },
"digital-ide.function.lsp.linter.vlog.diagnostor": { "digital-ide.function.lsp.linter.verilog.diagnostor": {
"type": "string", "type": "string",
"enumDescriptions": [ "enumDescriptions": [
"iverilog (© Icarus Verilog Project)",
"xvlog (© Xilinx, Inc.)",
"vlog (© Mentor Graphics Corporation)",
"verilator (© Verilator Project)",
"verible-verilog-syntax (© Google LLC)"
],
"enum": [
"iverilog",
"vivado", "vivado",
"modelsim", "modelsim",
"verilator", "verilator",
"verible" "verible"
], ],
"enum": [ "default": "vivado",
"vivado", "description": "%digital-ide.function.lsp.linter.verilog.diagnostor.title%"
"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%"
}, },
"digital-ide.function.lsp.linter.systemverilog.diagnostor": { "digital-ide.function.lsp.linter.systemverilog.diagnostor": {
"type": "string", "type": "string",
"enumDescriptions": [ "enumDescriptions": [
"use diagnostor in vivado", "xvlog (© Xilinx, Inc.)",
"use diagnostor in modelsim", "vlog (© Mentor Graphics Corporation)",
"use our buildin diagnostor" "verilator (© Verilator Project)",
"verible-verilog-syntax (© Google LLC)"
], ],
"enum": [ "enum": [
"vivado", "vivado",
"modelsim", "modelsim",
"default" "verilator",
"verible"
], ],
"default": "default", "default": "vivado",
"description": "%digital-ide.function.lsp.linter.systemverilog.diagnostor.title%" "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": { "digital-ide.function.instantiation.addComment": {
"description": "%digital-ide.function.instantiation.addComment.title%", "description": "%digital-ide.function.instantiation.addComment.title%",
"type": "boolean", "type": "boolean",

View File

@ -84,15 +84,18 @@
"digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "Indentation", "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-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.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.verilog.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.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.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.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.", "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", "fpga-support.onTypeFormattingTriggerCharacters.title": "Trigger characters for onTypeFormatting",
"digital-ide.function.lsp.file-parse-maxsize.title": "", "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.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": "" "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."
} }

View File

@ -84,15 +84,18 @@
"digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "インデント", "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-include.title": "モジュールの自動補完をトリガーするとき、トップの include マクロにインスタンス化されたモジュールがあるファイルが含まれていない場合、ファイルの先頭に `include \"xxx.v\" を自動的に追加します",
"digital-ide.function.lsp.completion.vlog.auto-add-output-declaration.title": "モジュールの自動補完をトリガーするとき、インスタンス化されたモジュールの上に output タイプの信号の宣言を自動的に生成します", "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.verilog.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.systemverilog.diagnostor.title": "SystemVerilog 編集時のリンターを行う診断器を選択します", "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.addComment.title": "インスタンス化時に // ポート, // 入力, // 出力 のようなコメントを追加し、モジュール呼び出しの補完を含みます",
"digital-ide.function.instantiation.autoNetOutputDeclaration.title": "インスタンス化が発生したときにスコープ内で出力タイプのネットを自動的に宣言します。", "digital-ide.function.instantiation.autoNetOutputDeclaration.title": "インスタンス化が発生したときにスコープ内で出力タイプのネットを自動的に宣言します。",
"fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting のトリガー文字", "fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting のトリガー文字",
"digital-ide.function.lsp.file-parse-maxsize.title": "", "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.verible.install.path.title": "verible のインストールディレクトリパス。つまり、verible-verilog-syntax 実行ファイルを含むフォルダの絶対パス。指定しない場合、デフォルトで verible-verilog-syntax が診断に使用されます。",
"digital-ide.prj.verilator.install.path.title": "" "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": "グローバルに無効化され、プロジェクト全体でプロジェクトエラーが報告されません。"
} }

View File

@ -84,15 +84,18 @@
"digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "Indentation", "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-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.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.verilog.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.systemverilog.diagnostor.title": "Choose the diagnostor to do linter in editing SystemVerilog", "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.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.", "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", "fpga-support.onTypeFormattingTriggerCharacters.title": "Trigger characters for onTypeFormatting",
"digital-ide.function.lsp.file-parse-maxsize.title": "", "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.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": "" "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."
} }

View File

@ -84,15 +84,18 @@
"digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "缩进", "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-include.title": "触发模块的自动补全时,如果顶部 include 宏中没有包含被例化模块所在的文件,则自动在文件顶部添加 `include \"xxx.v\"",
"digital-ide.function.lsp.completion.vlog.auto-add-output-declaration.title": "触发模块的自动补全时,在例化模块上方自动生成 output 类型信号的申明", "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.verilog.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.systemverilog.diagnostor.title": "选择编辑 SystemVerilog 时的诊断器进行语法检查", "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.addComment.title": "在进行实例化时添加注释,如 // 端口, // 输入, // 输出,包括模块调用的完成",
"digital-ide.function.instantiation.autoNetOutputDeclaration.title": "在实例化发生时自动在作用域中声明输出类型的网络。", "digital-ide.function.instantiation.autoNetOutputDeclaration.title": "在实例化发生时自动在作用域中声明输出类型的网络。",
"fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting 的触发字符", "fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting 的触发字符",
"digital-ide.function.lsp.file-parse-maxsize.title": "最大解析的文件阈值,大小超出这个值的文件不会被解析。单位为 MB必须是整数。默认为 1MB", "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.verible.install.path.title": "verible 的安装目录路径,也就是包含 verible-verilog-syntax 可执行文件的文件夹的绝对路径。如果不指定,默认采用 verible-verilog-syntax 执行诊断。",
"digital-ide.prj.verilator.install.path.title": "" "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": "全局关闭,即整个工程都不进行工程报错。"
} }

View File

@ -84,15 +84,18 @@
"digital-ide.function.lsp.formatter.vhdl.default.indentation.title": "縮進", "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-include.title": "觸發模塊的自動補全時,如果頂部 include 宏中沒有包含被例化模塊所在的文件,則自動在文件頂部添加 `include \"xxx.v\"",
"digital-ide.function.lsp.completion.vlog.auto-add-output-declaration.title": "觸發模塊的自動補全時,在例化模塊上方自動生成 output 類型信號的申明", "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.verilog.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.systemverilog.diagnostor.title": "選擇編輯 SystemVerilog 時的診斷器進行語法檢查", "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.addComment.title": "在進行實例化時添加註釋,如 // 端口, // 輸入, // 輸出,包括模塊調用的完成",
"digital-ide.function.instantiation.autoNetOutputDeclaration.title": "在實例化發生時自動在作用域中聲明輸出類型的網絡。", "digital-ide.function.instantiation.autoNetOutputDeclaration.title": "在實例化發生時自動在作用域中聲明輸出類型的網絡。",
"fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting 的觸發字符", "fpga-support.onTypeFormattingTriggerCharacters.title": "onTypeFormatting 的觸發字符",
"digital-ide.function.lsp.file-parse-maxsize.title": "", "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.verible.install.path.title": "verible 的安裝目錄路徑,也就是包含 verible-verilog-syntax 可執行文件的文件夾的絕對路徑。如果不指定,默認採用 verible-verilog-syntax 執行診斷。",
"digital-ide.prj.verilator.install.path.title": "" "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": "全局關閉,即整個工程都不進行工程報錯。"
} }

View File

@ -8,7 +8,6 @@ import * as treeView from './treeView';
import { tclCompletionProvider } from './lsp/completion/tcl'; import { tclCompletionProvider } from './lsp/completion/tcl';
import * as lspFormatter from '../../resources/formatter'; import * as lspFormatter from '../../resources/formatter';
import * as lspTranslator from '../../resources/translator'; import * as lspTranslator from '../../resources/translator';
import * as lspLinter from './lsp/linter';
import * as tool from './tool'; import * as tool from './tool';
@ -119,16 +118,6 @@ function registerLsp(context: vscode.ExtensionContext, version: string) {
// tcl lsp // tcl lsp
vscode.languages.registerCompletionItemProvider(tclSelector, tclCompletionProvider); 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);
} }

View File

@ -1,8 +1,9 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { LanguageClient } from 'vscode-languageclient/node'; import { LanguageClient } from 'vscode-languageclient/node';
import { UpdateConfigurationType } from '../../global/lsp'; 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 { HdlLangID } from '../../global/enum';
import * as lspLinter from '../lsp/linter';
interface ConfigItem { interface ConfigItem {
name: string, name: string,
@ -11,7 +12,13 @@ interface ConfigItem {
type CommonValue = string | boolean | number; 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 相关的配置 // 常规 lsp 相关的配置
const lspConfigures: ConfigItem[] = []; const lspConfigures: ConfigItem[] = [];
const properties = packageJson?.contributes?.configuration?.properties; 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, configs: lspConfigures,
configType: 'lsp' configType: 'lsp'
}); });
// 初始化,配置全部 linter 到后端 // 初始化,配置全部 linter 到后端
updateLinterConfiguration( await updateLinterConfiguration(
client, client,
linterCommand.VLOG_LINTER_CONFIG_NAME + '.diagnostor', Linter.getLinterConfigurationName(HdlLangID.Verilog),
getCurrentLinterName(HdlLangID.Verilog) Linter.getLinterName(HdlLangID.Verilog)
); );
updateLinterConfiguration( await updateLinterConfiguration(
client, client,
linterCommand.SVLOG_LINTER_CONFIG_NAME + '.diagnostor', Linter.getLinterConfigurationName(HdlLangID.SystemVerilog),
getCurrentLinterName(HdlLangID.SystemVerilog) Linter.getLinterName(HdlLangID.SystemVerilog)
); );
updateLinterConfiguration( await updateLinterConfiguration(
client, client,
linterCommand.VHDL_LINTER_CONFIG_NAME + '.diagnostor', Linter.getLinterConfigurationName(HdlLangID.Vhdl),
getCurrentLinterName(HdlLangID.Vhdl) Linter.getLinterName(HdlLangID.Vhdl)
); );
// 监听配置文件的变化,变化时需要做出的行为 // 监听配置文件的变化,变化时需要做出的行为
@ -69,80 +76,69 @@ export function registerConfigurationUpdater(client: LanguageClient, packageJson
}); });
} }
const currentLinterConfiguration = { // 本次更新时,当前各个语言正在使用的诊断器的名字的映射表
vlog: getCurrentLinterName(HdlLangID.Verilog), // 因为 getLinterName 需要进行一次映射,此处为后续的遍历预缓存一波
svlog: getCurrentLinterName(HdlLangID.SystemVerilog), const currentLinterConfiguration: Record<HdlLangID, string> = {
vhdl: getCurrentLinterName(HdlLangID.Vhdl) [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) { for (const linterName of supportLinters) {
const configuratioName = linterCommand.LinterInstallPathConfigurationNames[linterName]; const configuratioName = Linter.getLinterInstallConfigurationName(linterName);
if (event.affectsConfiguration(configuratioName)) { if (event.affectsConfiguration(configuratioName)) {
// 查看谁使用了这个诊断器,更新它的基本信息 // 查看谁使用了这个诊断器,更新它的基本信息
if (linterName === currentLinterConfiguration.vlog) { for (const langID of affectsLangIDs) {
await updateLinterConfiguration( if (linterName === currentLinterConfiguration[langID]) {
client, const linterConfigurationName = Linter.getLinterConfigurationName(langID);
linterCommand.VLOG_LINTER_CONFIG_NAME + '.diagnostor', await updateLinterConfiguration(client, linterConfigurationName, linterName);
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 { export async function registerLinter(client: LanguageClient) {
switch (langID) { // 初始化,配置全部 linter 到 linterManager
case HdlLangID.Verilog: lspLinter.vlogLinterManager.start(client);
return vscode.workspace.getConfiguration().get<linterCommand.SupportLinterName>( lspLinter.vhdlLinterManager.start(client);
linterCommand.VLOG_LINTER_CONFIG_NAME + '.diagnostor', lspLinter.svlogLinterManager.start(client);
'vivado'
);
case HdlLangID.Vhdl: // 对应配置文件的变动需要修改全局的相关变量
return vscode.workspace.getConfiguration().get<linterCommand.SupportLinterName>( vscode.workspace.onDidChangeConfiguration(async event => {
linterCommand.VHDL_LINTER_CONFIG_NAME + '.diagnostor', if (event.affectsConfiguration(Linter.getLinterConfigurationName(HdlLangID.Verilog))) {
'vivado' await lspLinter.vlogLinterManager.updateCurrentLinterItem(client);
); lspLinter.vlogLinterManager.updateStatusBar();
}
case HdlLangID.SystemVerilog:
return vscode.workspace.getConfiguration().get<linterCommand.SupportLinterName>(
linterCommand.SVLOG_LINTER_CONFIG_NAME + '.diagnostor',
'vivado'
);
default: if (event.affectsConfiguration(Linter.getLinterConfigurationName(HdlLangID.SystemVerilog))) {
break; await lspLinter.svlogLinterManager.updateCurrentLinterItem(client);
} lspLinter.svlogLinterManager.updateStatusBar();
return 'vivado'; }
if (event.affectsConfiguration(Linter.getLinterConfigurationName(HdlLangID.Vhdl))) {
await lspLinter.vhdlLinterManager.updateCurrentLinterItem(client);
lspLinter.vhdlLinterManager.updateStatusBar();
}
});
} }
async function updateLinterConfiguration( async function updateLinterConfiguration(
client: LanguageClient, client: LanguageClient,
configurationName: string, configurationName: string,
linterName: linterCommand.SupportLinterName linterName: Linter.SupportLinterName
) { ) {
const configuratioName = linterCommand.LinterInstallPathConfigurationNames[linterName]; const configuratioName = Linter.getLinterInstallConfigurationName(linterName);
const linterPath = vscode.workspace.getConfiguration().get<string>(configuratioName, ''); const linterPath = vscode.workspace.getConfiguration().get<string>(configuratioName, '');
console.log(linterName);
await client.sendRequest(UpdateConfigurationType, { await client.sendRequest(UpdateConfigurationType, {
configs: [ configs: [
{ name: configurationName, value: linterName }, { name: configurationName, value: linterName },
@ -150,4 +146,4 @@ async function updateLinterConfiguration(
], ],
configType: 'linter' configType: 'linter'
}); });
} }

View File

@ -15,7 +15,7 @@ import { IProgress, LspClient, opeParam } from '../../global';
import axios, { AxiosResponse } from "axios"; import axios, { AxiosResponse } from "axios";
import { chooseBestDownloadSource, getGiteeDownloadLink, getGithubDownloadLink, getPlatformPlatformSignature } from "./cdn"; import { chooseBestDownloadSource, getGiteeDownloadLink, getGithubDownloadLink, getPlatformPlatformSignature } from "./cdn";
import { hdlDir, hdlPath } from "../../hdlFs"; import { hdlDir, hdlPath } from "../../hdlFs";
import { registerConfigurationUpdater } from "./config"; import { registerConfigurationUpdater, registerLinter } from "./config";
import { t } from "../../i18n"; import { t } from "../../i18n";
function getLspServerExecutionName() { function getLspServerExecutionName() {
@ -214,7 +214,10 @@ export async function activate(context: vscode.ExtensionContext, packageJson: an
await client.start(); await client.start();
// 检测配置文件变动 // 检测配置文件变动
registerConfigurationUpdater(client, packageJson); await registerConfigurationUpdater(client, packageJson);
// 配置诊断器
await registerLinter(client);
} }

View File

@ -1,20 +0,0 @@
import * as vscode from 'vscode';
import { HdlLangID } from '../../../global/enum';
interface BaseLinter {
diagnostic: vscode.DiagnosticCollection;
lint(document: vscode.TextDocument): Promise<void>;
remove(uri: vscode.Uri): Promise<void>;
initialise(langID: HdlLangID): Promise<boolean>;
}
interface BaseManager {
initialise(): Promise<void>;
updateLinter(): Promise<boolean>;
}
export {
BaseLinter,
BaseManager
};

View File

@ -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<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 makeLinterNamePickItem(
client: LanguageClient,
langID: HdlLangID,
linterName: SupportLinterName
): Promise<LinterItem> {
const configuration = vscode.workspace.getConfiguration();
const linterInstallConfigurationName = LinterInstallPathConfigurationNames[linterName];
const linterPath = configuration.get<string>(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<LinterItem>();
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<LinterItem>();
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<LinterItem>();
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();
}

View File

@ -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<SupportLinterName>(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<LinterItem> {
const configuration = vscode.workspace.getConfiguration();
const linterInstallConfigurationName = getLinterInstallConfigurationName(linterName);
const linterPath = configuration.get<string>(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<LinterMode>('digital-ide.function.lsp.linter.linter-mode', LinterMode.Full);
}

View File

@ -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<void> {
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(`<default linter> 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<void> {
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(`<default linter> 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
};

View File

@ -1,14 +1,11 @@
import { vlogLinterManager } from './vlog'; import {
import { vhdlLinterManager } from './vhdl'; vlogLinterManager,
import { svlogLinterManager } from './svlog'; vhdlLinterManager,
svlogLinterManager
import { pickVlogLinter, pickVhdlLinter, pickSvlogLinter } from './command'; } from './manager';
export { export {
vlogLinterManager, vlogLinterManager,
vhdlLinterManager, vhdlLinterManager,
svlogLinterManager, svlogLinterManager
pickVlogLinter,
pickVhdlLinter,
pickSvlogLinter,
}; };

View File

@ -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<void> {
// 根据配置选择对应的诊断器
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<LinterItem>();
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'
]);

View File

@ -4,10 +4,9 @@ import * as fs from 'fs';
import { LspOutput, ReportType, opeParam } from "../../../global"; import { LspOutput, ReportType, opeParam } from "../../../global";
import { hdlFile, hdlPath } from "../../../hdlFs"; import { hdlFile, hdlPath } from "../../../hdlFs";
import { easyExec } from "../../../global/util"; import { easyExec } from "../../../global/util";
import { BaseLinter } from "./base";
import { HdlLangID } from "../../../global/enum"; import { HdlLangID } from "../../../global/enum";
class ModelsimLinter implements BaseLinter { class ModelsimLinter {
diagnostic: vscode.DiagnosticCollection; diagnostic: vscode.DiagnosticCollection;
executableFileMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>(); executableFileMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>();
executableInvokeNameMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>(); executableInvokeNameMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>();

View File

@ -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<void> {
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('<svlog lsp manager> 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<void> {
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<boolean> {
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(`<svlog lsp manager> 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<boolean> {
const selectedLinter = vivadoLinter;
let launch = true;
launch = await selectedLinter.initialise(HdlLangID.SystemVerilog);
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)';
LspOutput.report('<svlog lsp manager> 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('<svlog lsp manager> Fail to launch vivado linter', {
level: ReportType.Error
});
}
this.currentLinter = selectedLinter;
this.activateLinterName = 'vivado';
this.statusBarItem.show();
return launch;
}
public async activateModelsim(): Promise<boolean> {
const selectedLinter = modelsimLinter;
let launch = true;
launch = await selectedLinter.initialise(HdlLangID.SystemVerilog);
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)';
LspOutput.report('<svlog lsp manager> 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('<svlog lsp manager> Fail to launch modelsim linter', {
level: ReportType.Error
});
}
this.currentLinter = selectedLinter;
this.activateLinterName = 'modelsim';
this.statusBarItem.show();
return launch;
}
public async activateDefault(): Promise<boolean> {
const selectedLinter = defaultVlogLinter;
let launch = true;
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(default)';
LspOutput.report('<svlog lsp manager> 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('<svlog lsp manager> 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
};

View File

@ -4,12 +4,11 @@ import * as fs from 'fs';
import { LspOutput, ReportType, opeParam } from "../../../global"; import { LspOutput, ReportType, opeParam } from "../../../global";
import { hdlFile, hdlPath } from "../../../hdlFs"; import { hdlFile, hdlPath } from "../../../hdlFs";
import { easyExec } from "../../../global/util"; import { easyExec } from "../../../global/util";
import { BaseLinter } from "./base";
import { HdlLangID } from "../../../global/enum"; import { HdlLangID } from "../../../global/enum";
type Path = string; type Path = string;
class VerilatorLinter implements BaseLinter { class VerilatorLinter {
diagnostic: vscode.DiagnosticCollection; diagnostic: vscode.DiagnosticCollection;
executableFileMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>(); executableFileMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>();
executableInvokeNameMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>(); executableInvokeNameMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>();

View File

@ -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<void> {
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('<vhdl lsp manager> 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<void> {
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<boolean> {
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(`<vhdl lsp manager> 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<boolean> {
const selectedLinter = vivadoLinter;
let launch = true;
launch = await selectedLinter.initialise(HdlLangID.Vhdl);
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)';
LspOutput.report('<vhdl lsp manager> 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('<vhdl lsp manager> Fail to launch vivado linter', {
level: ReportType.Error
});
}
this.currentLinter = selectedLinter;
this.activateLinterName = 'vivado';
this.statusBarItem.show();
return launch;
}
public async activateModelsim(): Promise<boolean> {
const selectedLinter = modelsimLinter;
let launch = true;
launch = await selectedLinter.initialise(HdlLangID.Vhdl);
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)';
LspOutput.report('<vhdl lsp manager> 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('<vhdl lsp manager> Fail to launch modelsim linter', {
level: ReportType.Error
});
}
this.currentLinter = selectedLinter;
this.activateLinterName = 'modelsim';
this.statusBarItem.show();
return launch;
}
public async activateDefault(): Promise<boolean> {
const selectedLinter = defaultVhdlLinter;
let launch = true;
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(default)';
LspOutput.report('<vhdl lsp manager> 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('<vhdl lsp manager> 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
};

View File

@ -4,12 +4,11 @@ import * as fs from 'fs';
import { LspOutput, ReportType, opeParam } from "../../../global"; import { LspOutput, ReportType, opeParam } from "../../../global";
import { hdlFile, hdlPath } from "../../../hdlFs"; import { hdlFile, hdlPath } from "../../../hdlFs";
import { easyExec } from "../../../global/util"; import { easyExec } from "../../../global/util";
import { BaseLinter } from "./base";
import { HdlLangID } from "../../../global/enum"; import { HdlLangID } from "../../../global/enum";
type Path = string; type Path = string;
class VivadoLinter implements BaseLinter { class VivadoLinter {
diagnostic: vscode.DiagnosticCollection; diagnostic: vscode.DiagnosticCollection;
executableFileMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>(); executableFileMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>();
executableInvokeNameMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>(); executableInvokeNameMap: Map<HdlLangID, string | undefined> = new Map<HdlLangID, string>();

View File

@ -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<void> {
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('<vlog lsp manager> 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<void> {
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<boolean> {
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(`<vlog lsp manager> 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<boolean> {
const selectedLinter = vivadoLinter;
let launch = true;
launch = await selectedLinter.initialise(HdlLangID.Verilog);
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)';
LspOutput.report('<vlog lsp manager> 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('<vlog lsp manager> Fail to launch vivado linter', {
level: ReportType.Error
});
}
this.currentLinter = selectedLinter;
this.activateLinterName = 'vivado';
this.statusBarItem.show();
return launch;
}
public async activateModelsim(): Promise<boolean> {
const selectedLinter = modelsimLinter;
let launch = true;
launch = await selectedLinter.initialise(HdlLangID.Verilog);
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)';
LspOutput.report('<vlog lsp manager> 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('<vlog lsp manager> Fail to launch modelsim linter', {
level: ReportType.Error
});
}
this.currentLinter = selectedLinter;
this.activateLinterName = 'modelsim';
this.statusBarItem.show();
return launch;
}
public async activateDefault(): Promise<boolean> {
const selectedLinter = defaultVlogLinter;
let launch = true;
if (launch) {
this.statusBarItem.text = '$(getting-started-beginner) Linter(default)';
LspOutput.report('<vlog lsp manager> 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('<vlog lsp manager> 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
};

View File

@ -863,7 +863,6 @@ class HdlModule {
const instances = new Set<HdlInstance>(); const instances = new Set<HdlInstance>();
// 获取自身的 // 获取自身的
for (const inst of this.nameToInstances.values()) { for (const inst of this.nameToInstances.values()) {
console.log(inst);
instances.add(inst); instances.add(inst);
// 递归获取 inst 的 // 递归获取 inst 的
if (inst.module) { if (inst.module) {
@ -1148,8 +1147,6 @@ export class HdlFile {
// add to global hdlParam // add to global hdlParam
hdlParam.setHdlFile(this); hdlParam.setHdlFile(this);
console.log(modules);
// make nameToModule // make nameToModule
this.nameToModule = new Map<string, HdlModule>(); this.nameToModule = new Map<string, HdlModule>();
for (const rawHdlModule of modules) { for (const rawHdlModule of modules) {

View File

@ -164,17 +164,6 @@ export class HdlAction extends BaseAction {
// 下一个版本丢弃,完全由后端承担这部分功能 // 下一个版本丢弃,完全由后端承担这部分功能
async updateLinter(path: string) { 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);
}
} }
} }