diff --git a/l10n/bundle.l10n.de.json b/l10n/bundle.l10n.de.json index 22670bb..11a433f 100644 --- a/l10n/bundle.l10n.de.json +++ b/l10n/bundle.l10n.de.json @@ -91,5 +91,8 @@ "info.common.not-available": "{0} ist derzeit nicht verfügbar", "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" + "error.linter.status-bar.tooltip": "Kann Diagnose für {0} nicht abrufen", + "info.linter.status-bar.tooltip": "Diagnosegerät {0} arbeitet", + "warning.linter.cannot-get-valid-linter-invoker": "Die digitale IDE kann keinen Aufrufpfad für {0} abrufen. Bitte installieren Sie den entsprechenden Diagnose-Tool und konfigurieren Sie ihn entweder in der Umgebungsvariablen PATH oder im digitalen IDE-Diagnosetool-Installationspfad.", + "info.linter.config-linter-install-path": "Installationsverzeichnis konfigurieren" } \ No newline at end of file diff --git a/l10n/bundle.l10n.en.json b/l10n/bundle.l10n.en.json index ea02a69..7255ed1 100644 --- a/l10n/bundle.l10n.en.json +++ b/l10n/bundle.l10n.en.json @@ -91,5 +91,8 @@ "info.common.not-available": "{0} is currently unavailable", "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" + "error.linter.status-bar.tooltip": "Unable to get {0} diagnoser", + "info.linter.status-bar.tooltip": "Diagnostics {0} is working", + "warning.linter.cannot-get-valid-linter-invoker": "The Digital IDE cannot retrieve the call path for {0}. Please install the corresponding diagnostic tool and configure it either in the environment variable PATH or in the Digital IDE's diagnostic tool installation path.", + "info.linter.config-linter-install-path": "Configure installation directory" } \ No newline at end of file diff --git a/l10n/bundle.l10n.ja.json b/l10n/bundle.l10n.ja.json index 81132eb..26b172f 100644 --- a/l10n/bundle.l10n.ja.json +++ b/l10n/bundle.l10n.ja.json @@ -91,5 +91,8 @@ "info.common.not-available": "{0} は現在使用できません", "info.common.linter-name": "診断ツール", "info.linter.finish-init": "{0} 診断ツールの初期化が完了しました。現在の診断ツールの名前は {1} です", - "error.linter.status-bar.tooltip": "{0} 診断機能を取得できません" + "error.linter.status-bar.tooltip": "{0} 診断機能を取得できません", + "info.linter.status-bar.tooltip": "診断ツール {0} が作動中", + "warning.linter.cannot-get-valid-linter-invoker": "デジタルIDEは{0}の呼び出しパスを取得できません。対応する診断ツールをインストールし、環境変数PATHに設定するか、デジタルIDEの診断ツールインストールパスを設定してください。", + "info.linter.config-linter-install-path": "インストールディレクトリを設定" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json index 3c87324..37dc988 100644 --- a/l10n/bundle.l10n.zh-cn.json +++ b/l10n/bundle.l10n.zh-cn.json @@ -91,5 +91,8 @@ "info.common.not-available": "{0} 目前不可用", "info.common.linter-name": "诊断工具", "info.linter.finish-init": "完成 {0} 诊断器的初始化,当前诊断器的名字 {1}", - "error.linter.status-bar.tooltip": "无法获取 {0} 诊断器" + "error.linter.status-bar.tooltip": "无法获取 {0} 诊断器", + "info.linter.status-bar.tooltip": "诊断器 {0} 正在工作", + "warning.linter.cannot-get-valid-linter-invoker": "Digital IDE 无法获取到关于 {0} 的调用路径,请安装对应诊断器后,配置到环境变量 PATH 或者配置 Digital IDE 对应的诊断工具安装路径", + "info.linter.config-linter-install-path": "配置安装目录" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-tw.json b/l10n/bundle.l10n.zh-tw.json index 2f502d5..823e443 100644 --- a/l10n/bundle.l10n.zh-tw.json +++ b/l10n/bundle.l10n.zh-tw.json @@ -91,5 +91,8 @@ "info.common.not-available": "{0} 目前無法使用", "info.common.linter-name": "診斷工具", "info.linter.finish-init": "完成 {0} 診斷器的初始化,當前診斷器的名字 {1}", - "error.linter.status-bar.tooltip": "無法取得 {0} 診斷器" + "error.linter.status-bar.tooltip": "無法取得 {0} 診斷器", + "info.linter.status-bar.tooltip": "診斷器 {0} 正在運作", + "warning.linter.cannot-get-valid-linter-invoker": "Digital IDE 無法取得關於 {0} 的呼叫路徑,請安裝對應診斷器後,配置到環境變數 PATH 或者配置 Digital IDE 對應的診斷工具安裝路徑。", + "info.linter.config-linter-install-path": "配置安裝目錄" } \ No newline at end of file diff --git a/package.json b/package.json index 6b83a7d..7a58c21 100644 --- a/package.json +++ b/package.json @@ -299,6 +299,19 @@ "default": "full", "description": "%digital-ide.function.lsp.linter.linter-mode.title%" }, + "digital-ide.function.lsp.linter.linter-level": { + "type": "string", + "enumDescriptions": [ + "%digital-ide.function.lsp.linter.linter-level.error.title%", + "%digital-ide.function.lsp.linter.linter-level.warning.title%" + ], + "enum": [ + "error", + "warning" + ], + "default": "warning", + "description": "%digital-ide.function.lsp.linter.linter-level.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 cd4515b..150bb24 100644 --- a/package.nls.de.json +++ b/package.nls.de.json @@ -97,5 +97,8 @@ "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." + "digital-ide.function.lsp.linter.linter-mode.2.title": "Global deaktiviert, d.h. für das gesamte Projekt werden keine Projektfehler gemeldet.", + "digital-ide.function.lsp.linter.linter-level.title": "Diagnoselevel-Einstellungen des Linters", + "digital-ide.function.lsp.linter.linter-level.error.title": "Nur Fehler anzeigen", + "digital-ide.function.lsp.linter.linter-level.warning.title": "Fehler und Warnungen anzeigen" } \ No newline at end of file diff --git a/package.nls.ja.json b/package.nls.ja.json index 07812bd..1c6017e 100644 --- a/package.nls.ja.json +++ b/package.nls.ja.json @@ -97,5 +97,8 @@ "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": "グローバルに無効化され、プロジェクト全体でプロジェクトエラーが報告されません。" + "digital-ide.function.lsp.linter.linter-mode.2.title": "グローバルに無効化され、プロジェクト全体でプロジェクトエラーが報告されません。", + "digital-ide.function.lsp.linter.linter-level.title": "診断器の診断レベル設定", + "digital-ide.function.lsp.linter.linter-level.error.title": "エラーのみ表示", + "digital-ide.function.lsp.linter.linter-level.warning.title": "エラーと警告を表示" } \ No newline at end of file diff --git a/package.nls.json b/package.nls.json index 144768e..e94a291 100644 --- a/package.nls.json +++ b/package.nls.json @@ -97,5 +97,8 @@ "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." + "digital-ide.function.lsp.linter.linter-mode.2.title": "Globally disabled, meaning no project errors are reported for the entire project.", + "digital-ide.function.lsp.linter.linter-level.title": "Diagnostic Level Settings for the Linter", + "digital-ide.function.lsp.linter.linter-level.error.title": "Show Only Errors", + "digital-ide.function.lsp.linter.linter-level.warning.title": "Show Errors and Warnings" } \ No newline at end of file diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index 056b4f9..3270938 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -97,5 +97,8 @@ "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": "全局关闭,即整个工程都不进行工程报错。" + "digital-ide.function.lsp.linter.linter-mode.2.title": "全局关闭,即整个工程都不进行工程报错。", + "digital-ide.function.lsp.linter.linter-level.title": "诊断器诊断等级设置", + "digital-ide.function.lsp.linter.linter-level.error.title": "只显示错误", + "digital-ide.function.lsp.linter.linter-level.warning.title": "显示错误和警告" } \ No newline at end of file diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index de81213..3a5cafa 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -97,5 +97,8 @@ "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": "全局關閉,即整個工程都不進行工程報錯。" + "digital-ide.function.lsp.linter.linter-mode.2.title": "全局關閉,即整個工程都不進行工程報錯。", + "digital-ide.function.lsp.linter.linter-level.title": "診斷器診斷等級設置", + "digital-ide.function.lsp.linter.linter-level.error.title": "只顯示錯誤", + "digital-ide.function.lsp.linter.linter-level.warning.title": "顯示錯誤和警告" } \ No newline at end of file diff --git a/src/function/index.ts b/src/function/index.ts index 0b61fd6..0dfb863 100644 --- a/src/function/index.ts +++ b/src/function/index.ts @@ -18,9 +18,6 @@ import * as WaveView from './dide-viewer'; import { ModuleDataItem } from './treeView/tree'; import { downloadLsp } from './lsp-client'; import { hdlPath } from '../hdlFs'; -import { LspClient, opeParam } from '../global'; -import { DoFastToolChainType, SyncFastRequestType } from '../global/lsp'; -import { makeDocBody } from './hdlDoc/html'; function registerDocumentation(context: vscode.ExtensionContext) { vscode.commands.registerCommand('digital-ide.hdlDoc.showWebview', async (uri: vscode.Uri) => { diff --git a/src/function/lsp-client/cdn.ts b/src/function/lsp-client/cdn.ts index 012e7ed..0daffdd 100644 --- a/src/function/lsp-client/cdn.ts +++ b/src/function/lsp-client/cdn.ts @@ -1,46 +1,6 @@ -import * as os from 'os'; import axios from 'axios'; import { performance } from 'perf_hooks'; -enum IPlatformSignature { - x86Windows = 'windows_amd64', - aach64Windows = 'windows_aarch64', - x86Darwin = 'darwin_amd64', - aarch64Darwin = 'darwin_aarch64', - x86Linux = 'linux_amd64', - aarch64Linux = 'linux_aarch64', - unsupport = 'unsupport' -}; - -export function getPlatformPlatformSignature(): IPlatformSignature { - // Possible values are `'arm'`, `'arm64'`, `'ia32'`, `'mips'`,`'mipsel'`, `'ppc'`, `'ppc64'`, `'s390'`, `'s390x'`, `'x32'`, and `'x64'` - const arch = os.arch(); - - // Possible values are `'aix'`, `'darwin'`, `'freebsd'`,`'linux'`, `'openbsd'`, `'sunos'`, and `'win32'`. - const osName = os.platform(); - - switch (arch) { - case 'arm': - case 'arm64': - switch (osName) { - case 'win32': return IPlatformSignature.aach64Windows; - case 'darwin': return IPlatformSignature.aarch64Darwin; - case 'linux': return IPlatformSignature.aarch64Linux; - default: return IPlatformSignature.unsupport; - } - - case 'x32': - case 'x64': - switch (osName) { - case 'win32': return IPlatformSignature.x86Windows; - case 'darwin': return IPlatformSignature.x86Darwin; - case 'linux': return IPlatformSignature.x86Linux; - default: return IPlatformSignature.unsupport; - } - - default: return IPlatformSignature.unsupport; - } -} // const link1 = 'https://gitee.com/Digital-IDE/Digital-IDE/releases/download/0.4.0/digital-lsp_0.4.0_darwin_aarch64.tar.gz'; // const link2 = 'https://github.com/Digital-EDA/Digital-IDE/releases/download/0.4.0/digital-lsp_0.4.0_darwin_aarch64.tar.gz'; diff --git a/src/function/lsp-client/config.ts b/src/function/lsp-client/config.ts index 43f318e..74048de 100644 --- a/src/function/lsp-client/config.ts +++ b/src/function/lsp-client/config.ts @@ -40,18 +40,30 @@ export async function registerConfigurationUpdater(client: LanguageClient, packa }); // 初始化,配置全部 linter 到后端 + await updateLinterInstallPathConfiguration( + client, + Linter.getLinterConfigurationName(HdlLangID.Verilog) + ); await updateLinterConfiguration( client, Linter.getLinterConfigurationName(HdlLangID.Verilog), Linter.getLinterName(HdlLangID.Verilog) ); + await updateLinterInstallPathConfiguration( + client, + Linter.getLinterConfigurationName(HdlLangID.SystemVerilog) + ); await updateLinterConfiguration( client, Linter.getLinterConfigurationName(HdlLangID.SystemVerilog), Linter.getLinterName(HdlLangID.SystemVerilog) ); + await updateLinterInstallPathConfiguration( + client, + Linter.getLinterConfigurationName(HdlLangID.Vhdl) + ); await updateLinterConfiguration( client, Linter.getLinterConfigurationName(HdlLangID.Vhdl), @@ -84,6 +96,13 @@ export async function registerConfigurationUpdater(client: LanguageClient, packa [HdlLangID.Vhdl]: Linter.getLinterName(HdlLangID.Vhdl), [HdlLangID.Unknown]: HdlLangID.Unknown }; + + const linterManager: Record = { + [HdlLangID.Verilog]: lspLinter.vlogLinterManager, + [HdlLangID.SystemVerilog]: lspLinter.svlogLinterManager, + [HdlLangID.Vhdl]: lspLinter.vhdlLinterManager, + [HdlLangID.Unknown]: lspLinter.reserveLinterManager + }; // 需要讨论的可能受到配置文件更新影响 linter 功能的语言列表 const affectsLangIDs = [HdlLangID.Verilog, HdlLangID.SystemVerilog, HdlLangID.Vhdl]; @@ -96,7 +115,11 @@ export async function registerConfigurationUpdater(client: LanguageClient, packa for (const langID of affectsLangIDs) { if (linterName === currentLinterConfiguration[langID]) { const linterConfigurationName = Linter.getLinterConfigurationName(langID); + // 低频操作,随便糟蹋 await updateLinterConfiguration(client, linterConfigurationName, linterName); + // 更新当前诊断器状态 + await linterManager[langID].updateCurrentLinterItem(); + linterManager[langID].updateStatusBar(); } } } @@ -129,16 +152,27 @@ export async function registerLinter(client: LanguageClient) { }); } +/** + * @description 更新所有诊断器的路径信息到后端 + */ +async function updateLinterInstallPathConfiguration( + client: LanguageClient, + configurationName: string +) { + for (const linterName of Linter.SupportLinters) { + await updateLinterConfiguration(client, configurationName, linterName); + } +} + +/** + * @description 更新当前诊断器的所有信息到后端 + */ async function updateLinterConfiguration( client: LanguageClient, configurationName: string, linterName: Linter.SupportLinterName ) { - const configuratioName = Linter.getLinterInstallConfigurationName(linterName); - const linterPath = vscode.workspace.getConfiguration().get(configuratioName, ''); - - console.log(linterName); - + const linterPath = Linter.getLinterInstallPath(linterName); await client.sendRequest(UpdateConfigurationType, { configs: [ { name: configurationName, value: linterName }, diff --git a/src/function/lsp-client/index.ts b/src/function/lsp-client/index.ts index 8d3d309..af17c89 100644 --- a/src/function/lsp-client/index.ts +++ b/src/function/lsp-client/index.ts @@ -13,10 +13,11 @@ import * as tar from 'tar'; import { platform } from "os"; import { IProgress, LspClient, opeParam } from '../../global'; import axios, { AxiosResponse } from "axios"; -import { chooseBestDownloadSource, getGiteeDownloadLink, getGithubDownloadLink, getPlatformPlatformSignature } from "./cdn"; +import { chooseBestDownloadSource } from "./cdn"; import { hdlDir, hdlPath } from "../../hdlFs"; import { registerConfigurationUpdater, registerLinter } from "./config"; import { t } from "../../i18n"; +import { getPlatformPlatformSignature } from "../../global/util"; function getLspServerExecutionName() { const osname = platform(); @@ -198,7 +199,8 @@ export async function activate(context: vscode.ExtensionContext, packageJson: an workspaceFolder, initializationOptions: { extensionPath, - toolChain: opeParam.prjInfo.toolChain + toolChain: opeParam.prjInfo.toolChain, + version: version } }; diff --git a/src/function/lsp/linter/common.ts b/src/function/lsp/linter/common.ts index 7c42ef9..d6d9aa0 100644 --- a/src/function/lsp/linter/common.ts +++ b/src/function/lsp/linter/common.ts @@ -26,6 +26,7 @@ export let _selectVhdlLinterItem: LinterItem | undefined = undefined; // verible digital-ide.prj.verible.install.path // verilator digital-ide.prj.verilator.install.path export type SupportLinterName = 'iverilog' | 'vivado' | 'modelsim' | 'verible' | 'verilator'; +export const SupportLinters: SupportLinterName[] = ['iverilog', 'vivado', 'modelsim', 'verible', 'verilator']; /** * @description 获取指向【当前的 linter 的名字】的配置的名字,比如 `digital-ide.function.lsp.linter.verilog.diagnostor` @@ -52,6 +53,12 @@ export function getLinterInstallConfigurationName(linterName: SupportLinterName) return `digital-ide.prj.${linterName}.install.path`; } +export function getLinterInstallPath(linterName: SupportLinterName): string { + const configuration = vscode.workspace.getConfiguration(); + const linterInstallConfigurationName = getLinterInstallConfigurationName(linterName); + return configuration.get(linterInstallConfigurationName, ''); +} + /** * @description 生成 PickItem,这个过程中会对当前 linterName 的有效性进行校验 * @param client @@ -64,23 +71,27 @@ export async function makeLinterNamePickItem( langID: HdlLangID, linterName: SupportLinterName ): Promise { - const configuration = vscode.workspace.getConfiguration(); - const linterInstallConfigurationName = getLinterInstallConfigurationName(linterName); - const linterPath = configuration.get(linterInstallConfigurationName, ''); + const linterPath = getLinterInstallPath(linterName); const linterStatus = await client.sendRequest(LinterStatusRequestType, { languageId: langID, linterName, linterPath }); - + + const labelIcon = linterStatus.available ? 'getting-started-beginner': 'extensions-warning-message'; + + const detail = linterStatus.available ? + t('info.common.some-is-ready', linterStatus.invokeName) : + t("info.common.not-available", linterStatus.invokeName); + return { - label: '$(getting-started-beginner) ' + linterName, + label: `$(${labelIcon}) ` + linterName, name: linterName, linterPath, available: linterStatus.available, description: linterStatus.toolName, - detail: t('info.common.some-is-ready', linterStatus.invokeName) + detail } } @@ -109,4 +120,9 @@ export enum LinterMode { export function getLinterMode(): LinterMode { return vscode.workspace.getConfiguration().get('digital-ide.function.lsp.linter.linter-mode', LinterMode.Full); +} + +export interface IConfigReminder { + title: string, + value: 'config' | 'download' } \ No newline at end of file diff --git a/src/function/lsp/linter/index.ts b/src/function/lsp/linter/index.ts index d538760..d9d5fc3 100644 --- a/src/function/lsp/linter/index.ts +++ b/src/function/lsp/linter/index.ts @@ -1,11 +1,15 @@ import { vlogLinterManager, vhdlLinterManager, - svlogLinterManager + svlogLinterManager, + reserveLinterManager, + LinterManager } from './manager'; export { vlogLinterManager, vhdlLinterManager, - svlogLinterManager + svlogLinterManager, + reserveLinterManager, + LinterManager }; \ No newline at end of file diff --git a/src/function/lsp/linter/manager.ts b/src/function/lsp/linter/manager.ts index 9e25a34..aacc872 100644 --- a/src/function/lsp/linter/manager.ts +++ b/src/function/lsp/linter/manager.ts @@ -1,13 +1,13 @@ import * as vscode from 'vscode'; -import { LspClient, LspOutput, ReportType } from '../../../global'; +import { LspClient, LinterOutput, 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 { getLinterConfigurationName, getLinterInstallConfigurationName, getLinterName, IConfigReminder, LinterItem, LinterMode, makeLinterNamePickItem, makeLinterOptions, SupportLinterName, updateLinterConfigurationName } from './common'; +import { UpdateConfigurationType } from '../../../global/lsp'; import { LanguageClient } from 'vscode-languageclient/node'; -class LinterManager { +export class LinterManager { /** * @description 当前诊断器管理者绑定的语言 */ @@ -115,7 +115,7 @@ class LinterManager { this.statusBarItem.hide(); } - LspOutput.report(t('info.linter.finish-init', "verilog", this.currentLinterItem?.name || 'unknown'), { + LinterOutput.report(t('info.linter.finish-init', this.langID, this.currentLinterItem?.name || 'unknown'), { level: ReportType.Launch }); } @@ -145,16 +145,38 @@ class LinterManager { public updateStatusBar() { const statusBarItem = this.statusBarItem; const currentLinterItem = this.currentLinterItem; - if (currentLinterItem) { + if (currentLinterItem) { if (currentLinterItem.available) { + // 当前诊断器正常 + statusBarItem.backgroundColor = new vscode.ThemeColor('statusBar.background'); + statusBarItem.tooltip = t('info.linter.status-bar.tooltip', currentLinterItem.name); statusBarItem.text = `$(getting-started-beginner) Linter(${currentLinterItem.name})`; + LinterOutput.report(t('info.linter.finish-init', this.langID, 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), { + LinterOutput.report(t('error.linter.status-bar.tooltip', currentLinterItem.name), { level: ReportType.Error }); + // 当前诊断器不可用,遂提醒用户【配置文件】or【下载(如果有的话)】 + vscode.window.showWarningMessage( + t('warning.linter.cannot-get-valid-linter-invoker', currentLinterItem.name), + { title: t('info.linter.config-linter-install-path'), value: "config" }, + ).then(async res => { + // 用户选择配置 + if (res?.value === 'config') { + const linterInstallConfigurationName = getLinterInstallConfigurationName(currentLinterItem.name); + await vscode.commands.executeCommand('workbench.action.openSettings', linterInstallConfigurationName); + } + // 用户选择下载 + if (res?.value === 'download') { + + } + }); + + } statusBarItem.show(); } @@ -221,8 +243,7 @@ class LinterManager { pickWidget.onDidAccept(async () => { if (this.currentLinterItem) { - // 更新 vscode 配置文件 - updateLinterConfigurationName(this.langID, this.currentLinterItem.name); + // 更新后端 await client.sendRequest(UpdateConfigurationType, { configs: [ @@ -231,8 +252,9 @@ class LinterManager { ], configType: 'linter' }); - // 更新 status bar - this.updateStatusBar(); + // 更新 vscode 配置文件,这会改变配置,顺便触发一次 this.updateStatusBar() + // 详细请见 async function registerLinter(client: LanguageClient) + updateLinterConfigurationName(this.langID, this.currentLinterItem.name); pickWidget.hide(); } @@ -258,4 +280,5 @@ export const svlogLinterManager = new LinterManager(HdlLangID.SystemVerilog, [ 'verible', 'verilator', 'vivado' -]); \ No newline at end of file +]); +export const reserveLinterManager = new LinterManager(HdlLangID.Unknown, []); \ No newline at end of file diff --git a/src/function/lsp/linter/modelsim.ts b/src/function/lsp/linter/modelsim.ts index a973660..1562241 100644 --- a/src/function/lsp/linter/modelsim.ts +++ b/src/function/lsp/linter/modelsim.ts @@ -1,7 +1,7 @@ import * as vscode from "vscode"; import * as fs from 'fs'; -import { LspOutput, ReportType, opeParam } from "../../../global"; +import { LinterOutput, ReportType, opeParam } from "../../../global"; import { hdlFile, hdlPath } from "../../../hdlFs"; import { easyExec } from "../../../global/util"; import { HdlLangID } from "../../../global/enum"; @@ -49,7 +49,7 @@ class ModelsimLinter { this.diagnostic.set(document.uri, diagnostics); } } else { - LspOutput.report('modelsim linter is not available, please check prj.modelsim.install.path in your setting!', { + LinterOutput.report('modelsim linter is not available, please check prj.modelsim.install.path in your setting!', { level: ReportType.Error, notify: true }); @@ -74,7 +74,7 @@ class ModelsimLinter { if (headerInfo === 'Error') { const errorLine = parseInt(tokens[2]) - 1; const syntaxInfo = tokens[5]; - LspOutput.report(` line: ${errorLine}, info: ${syntaxInfo}`, { + LinterOutput.report(` line: ${errorLine}, info: ${syntaxInfo}`, { level: ReportType.Run }); @@ -84,7 +84,7 @@ class ModelsimLinter { } else if (headerInfo === 'Warning') { const errorLine = parseInt(tokens[2]) - 1; const syntaxInfo = tokens[5]; - LspOutput.report(` line: ${errorLine}, info: ${syntaxInfo}`, { + LinterOutput.report(` line: ${errorLine}, info: ${syntaxInfo}`, { level: ReportType.Run }); @@ -143,15 +143,15 @@ class ModelsimLinter { const fullExecutorName = opeParam.os === 'win32' ? executorName + '.exe' : executorName; if (modelsimInstallPath.trim() === '' || !fs.existsSync(modelsimInstallPath)) { - LspOutput.report(`User's modelsim Install Path "${modelsimInstallPath}", which is invalid. Use ${executorName} in default.`, { + LinterOutput.report(`User's modelsim Install Path "${modelsimInstallPath}", which is invalid. Use ${executorName} in default.`, { level: ReportType.Warn }); - LspOutput.report('If you have doubts, check prj.modelsim.install.path in setting', { + LinterOutput.report('If you have doubts, check prj.modelsim.install.path in setting', { level: ReportType.Warn }); return executorName; } else { - LspOutput.report(`User's modelsim Install Path "${modelsimInstallPath}", which is invalid`); + LinterOutput.report(`User's modelsim Install Path "${modelsimInstallPath}", which is invalid`); const executorPath = hdlPath.join( hdlPath.toSlash(modelsimInstallPath), @@ -172,13 +172,13 @@ class ModelsimLinter { const { stderr } = await easyExec(executorPath, []); if (stderr.length === 0) { this.executableInvokeNameMap.set(langID, executorPath); - LspOutput.report(`success to verify ${executorPath}, linter from modelsim is ready to go!`, { + LinterOutput.report(`success to verify ${executorPath}, linter from modelsim is ready to go!`, { level: ReportType.Launch }); return true; } else { this.executableInvokeNameMap.set(langID, undefined); - LspOutput.report(`Fail to execute ${executorPath}! Reason: ${stderr}`, { + LinterOutput.report(`Fail to execute ${executorPath}! Reason: ${stderr}`, { level: ReportType.Error, notify: true }); diff --git a/src/function/lsp/linter/verilator.ts b/src/function/lsp/linter/verilator.ts index 06668b0..3b0ed76 100644 --- a/src/function/lsp/linter/verilator.ts +++ b/src/function/lsp/linter/verilator.ts @@ -1,7 +1,7 @@ import * as vscode from "vscode"; import * as fs from 'fs'; -import { LspOutput, ReportType, opeParam } from "../../../global"; +import { LinterOutput, ReportType, opeParam } from "../../../global"; import { hdlFile, hdlPath } from "../../../hdlFs"; import { easyExec } from "../../../global/util"; import { HdlLangID } from "../../../global/enum"; @@ -49,7 +49,7 @@ class VerilatorLinter { this.diagnostic.set(document.uri, diagnostics); } } else { - LspOutput.report('verilator linter is not available, please check prj.verilator.install.path in your setting', { + LinterOutput.report('verilator linter is not available, please check prj.verilator.install.path in your setting', { level: ReportType.Error, notify: true }); @@ -120,15 +120,15 @@ class VerilatorLinter { const fullExecutorName = opeParam.os === 'win32' ? executorName + '.exe' : executorName; if (verilatorInstallPath.trim() === '' || !fs.existsSync(verilatorInstallPath)) { - LspOutput.report(`User's verilator Install Path ${verilatorInstallPath}, which is invalid. Use ${executorName} in default.`, { + LinterOutput.report(`User's verilator Install Path ${verilatorInstallPath}, which is invalid. Use ${executorName} in default.`, { level: ReportType.Warn }); - LspOutput.report('If you have doubts, check prj.verilator.install.path in setting', { + LinterOutput.report('If you have doubts, check prj.verilator.install.path in setting', { level: ReportType.Warn }); return executorName; } else { - LspOutput.report(`User's verilator Install Path ${verilatorInstallPath}, which is invalid`); + LinterOutput.report(`User's verilator Install Path ${verilatorInstallPath}, which is invalid`); const executorPath = hdlPath.join( hdlPath.toSlash(verilatorInstallPath), @@ -149,7 +149,7 @@ class VerilatorLinter { const { stderr } = await easyExec(executorPath, []); if (stderr.length === 0) { this.executableInvokeNameMap.set(langID, executorPath); - LspOutput.report(`success to verify ${executorPath}, linter from verilator is ready to go!`, { + LinterOutput.report(`success to verify ${executorPath}, linter from verilator is ready to go!`, { level: ReportType.Launch }); return true; @@ -157,7 +157,7 @@ class VerilatorLinter { this.executableInvokeNameMap.set(langID, undefined); console.log(stderr); - LspOutput.report(`Fail to execute ${executorPath}! Reason: ${stderr}`, { + LinterOutput.report(`Fail to execute ${executorPath}! Reason: ${stderr}`, { level: ReportType.Error, notify: true }); diff --git a/src/function/lsp/linter/vivado.ts b/src/function/lsp/linter/vivado.ts index 157679d..83f37e5 100644 --- a/src/function/lsp/linter/vivado.ts +++ b/src/function/lsp/linter/vivado.ts @@ -1,7 +1,7 @@ import * as vscode from "vscode"; import * as fs from 'fs'; -import { LspOutput, ReportType, opeParam } from "../../../global"; +import { LinterOutput, ReportType, opeParam } from "../../../global"; import { hdlFile, hdlPath } from "../../../hdlFs"; import { easyExec } from "../../../global/util"; import { HdlLangID } from "../../../global/enum"; @@ -54,7 +54,7 @@ class VivadoLinter { this.diagnostic.set(document.uri, diagnostics); } } else { - LspOutput.report('vivado linter is not available, please check prj.vivado.install.path in your setting', { + LinterOutput.report('vivado linter is not available, please check prj.vivado.install.path in your setting', { level: ReportType.Error, notify: true }); @@ -81,7 +81,7 @@ class VivadoLinter { if (headerInfo === 'ERROR') { const errorInfos = parsedPath.split(':'); const errorLine = Math.max(parseInt(errorInfos[errorInfos.length - 1]) - 1, 0); - LspOutput.report(` line: ${errorLine}, info: ${syntaxInfo}`, { + LinterOutput.report(` line: ${errorLine}, info: ${syntaxInfo}`, { level: ReportType.Run }); @@ -140,16 +140,16 @@ class VivadoLinter { const fullExecutorName = opeParam.os === 'win32' ? executorName + '.bat' : executorName; if (vivadoInstallPath.trim() === '' || !fs.existsSync(vivadoInstallPath)) { - LspOutput.report(`User's Vivado Install Path "${vivadoInstallPath}", which is invalid. Use ${executorName} in default.`, { + LinterOutput.report(`User's Vivado Install Path "${vivadoInstallPath}", which is invalid. Use ${executorName} in default.`, { level: ReportType.Warn }); - LspOutput.report('If you have doubts, check prj.vivado.install.path in setting', { + LinterOutput.report('If you have doubts, check prj.vivado.install.path in setting', { level: ReportType.Warn }); return executorName; } else { - LspOutput.report(`User's Vivado Install Path "${vivadoInstallPath}", which is invalid`); + LinterOutput.report(`User's Vivado Install Path "${vivadoInstallPath}", which is invalid`); const executorPath = hdlPath.join( hdlPath.toSlash(vivadoInstallPath), @@ -170,13 +170,13 @@ class VivadoLinter { const { stderr } = await easyExec(executorPath, []); if (stderr.length === 0) { this.executableInvokeNameMap.set(langID, executorPath); - LspOutput.report(`success to verify ${executorPath}, linter from vivado is ready to go!`, { + LinterOutput.report(`success to verify ${executorPath}, linter from vivado is ready to go!`, { level: ReportType.Launch }); return true; } else { this.executableInvokeNameMap.set(langID, undefined); - LspOutput.report(`Fail to execute ${executorPath}! Reason: ${stderr}`, { + LinterOutput.report(`Fail to execute ${executorPath}! Reason: ${stderr}`, { level: ReportType.Error, notify: true }); diff --git a/src/function/lsp/util/feature.ts b/src/function/lsp/util/feature.ts index 45c21b6..09df001 100644 --- a/src/function/lsp/util/feature.ts +++ b/src/function/lsp/util/feature.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ import * as vscode from 'vscode'; -import { AbsPath, LspOutput } from '../../../global'; +import { AbsPath, LinterOutput } from '../../../global'; import { HdlLangID } from '../../../global/enum'; import { hdlPath, hdlFile } from '../../../hdlFs'; import { Range } from '../../../hdlParser/common'; @@ -278,7 +278,7 @@ async function getFullSymbolInfo(document: vscode.TextDocument, range: Range, no while (line) { line --; content = document.lineAt(line).text; - LspOutput.report(content); + LinterOutput.report(content); // 首先判断该行是否是空白 if (content.trim().length === 0) { diff --git a/src/global/index.ts b/src/global/index.ts index 5e4b2ba..960e1d9 100644 --- a/src/global/index.ts +++ b/src/global/index.ts @@ -1,6 +1,6 @@ import { opeParam, OpeParamDefaults } from './opeParam'; import { PrjInfo, PrjInfoDefaults } from './prjInfo'; -import { MainOutput, LspOutput, YosysOutput, WaveViewOutput, ReportType } from './outputChannel'; +import { MainOutput, LinterOutput, YosysOutput, WaveViewOutput, ReportType } from './outputChannel'; import * as Enum from './enum'; import * as Lang from './lang'; @@ -27,7 +27,7 @@ export { AbsPath, RelPath, MainOutput, - LspOutput, + LinterOutput, YosysOutput, WaveViewOutput, ReportType, diff --git a/src/global/outputChannel.ts b/src/global/outputChannel.ts index 93cd4d2..d6499f6 100644 --- a/src/global/outputChannel.ts +++ b/src/global/outputChannel.ts @@ -117,7 +117,7 @@ class Output { } const MainOutput = new Output('Digital-IDE'); -const LspOutput = new Output('Digital-IDE Linter'); +const LinterOutput = new Output('Digital-IDE Linter'); const YosysOutput = new Output('Digital-IDE Yosys'); const WaveViewOutput = new Output('Digital-IDE Wave Viewer'); const HardwareOutput = new Output('Digital-IDE Hareware'); @@ -126,7 +126,7 @@ const HardwareErrorOutput = new Output('Digital-IDE Hareware Error'); export { ReportType, MainOutput, - LspOutput, + LinterOutput, YosysOutput, WaveViewOutput, HardwareOutput, diff --git a/src/global/util.ts b/src/global/util.ts index 23741b2..e2f32d2 100644 --- a/src/global/util.ts +++ b/src/global/util.ts @@ -1,4 +1,5 @@ import * as fs from 'fs'; +import * as os from 'os'; import * as vscode from 'vscode'; import * as childProcess from 'child_process'; @@ -113,4 +114,50 @@ export function debounce(fn: (...args: any[]) => any, timeout: number) { fn(...args); }, timeout); }; +} + +/** + * @description 平台签名 + */ +export enum IPlatformSignature { + x86Windows = 'windows_amd64', + aach64Windows = 'windows_aarch64', + x86Darwin = 'darwin_amd64', + aarch64Darwin = 'darwin_aarch64', + x86Linux = 'linux_amd64', + aarch64Linux = 'linux_aarch64', + unsupport = 'unsupport' +}; + +/** + * @description 获取平台签名 + */ +export function getPlatformPlatformSignature(): IPlatformSignature { + // Possible values are `'arm'`, `'arm64'`, `'ia32'`, `'mips'`,`'mipsel'`, `'ppc'`, `'ppc64'`, `'s390'`, `'s390x'`, `'x32'`, and `'x64'` + const arch = os.arch(); + + // Possible values are `'aix'`, `'darwin'`, `'freebsd'`,`'linux'`, `'openbsd'`, `'sunos'`, and `'win32'`. + const osName = os.platform(); + + switch (arch) { + case 'arm': + case 'arm64': + switch (osName) { + case 'win32': return IPlatformSignature.aach64Windows; + case 'darwin': return IPlatformSignature.aarch64Darwin; + case 'linux': return IPlatformSignature.aarch64Linux; + default: return IPlatformSignature.unsupport; + } + + case 'x32': + case 'x64': + switch (osName) { + case 'win32': return IPlatformSignature.x86Windows; + case 'darwin': return IPlatformSignature.x86Darwin; + case 'linux': return IPlatformSignature.x86Linux; + default: return IPlatformSignature.unsupport; + } + + default: return IPlatformSignature.unsupport; + } } \ No newline at end of file diff --git a/src/monitor/hdl.ts b/src/monitor/hdl.ts index 5f6b023..8df3eb5 100644 --- a/src/monitor/hdl.ts +++ b/src/monitor/hdl.ts @@ -6,12 +6,9 @@ import { AbsPath, MainOutput, opeParam, ReportType } from '../global'; import { hdlFile, hdlPath } from '../hdlFs'; import { hdlParam, HdlSymbol } from '../hdlParser'; import type { HdlMonitor } from './index'; -import { HdlLangID } from '../global/enum'; -import { vlogLinterManager, vhdlLinterManager, svlogLinterManager } from '../function/lsp/linter'; import { BaseAction, Event } from './event'; import { hdlIgnore } from '../manager/ignore'; - export class HdlAction extends BaseAction { selectFSWatcher(m: HdlMonitor): chokidar.FSWatcher | undefined { return m.hdlMonitor; @@ -68,16 +65,6 @@ export class HdlAction extends BaseAction { hdlParam.deleteHdlFile(path); refreshArchTree(); - - const uri = vscode.Uri.file(path); - const langID = hdlFile.getLanguageId(path); - if (langID === HdlLangID.Verilog) { - vlogLinterManager.remove(uri); - } else if (langID === HdlLangID.Vhdl) { - vhdlLinterManager.remove(uri); - } else if (langID === HdlLangID.SystemVerilog) { - svlogLinterManager.remove(uri); - } } /**