diff --git a/images/svg/dark/dide.svg b/images/svg/dark/dide.svg new file mode 100644 index 0000000..28ba1ed --- /dev/null +++ b/images/svg/dark/dide.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/svg/light/dide.svg b/images/svg/light/dide.svg new file mode 100644 index 0000000..28ba1ed --- /dev/null +++ b/images/svg/light/dide.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l10n/bundle.l10n.de.json b/l10n/bundle.l10n.de.json index 11a147a..01cf885 100644 --- a/l10n/bundle.l10n.de.json +++ b/l10n/bundle.l10n.de.json @@ -81,6 +81,5 @@ "error.simulation.error-happen-run-command": "Fehler bei der Icarus-Simulation:", "info.command.structure.transform-xilinx-to-standard": "Konvertiere Xilinx-Projektstruktur in Digital IDE-Standardstruktur", "error.command.structure.not-valid-xilinx-project": "Das aktuelle Projekt ist kein gültiges Xilinx-Projekt, die Konvertierung ist fehlgeschlagen!", - "info.command.structure.reload-vscode": "Projektstrukturkonvertierung abgeschlossen, bitte starten Sie vscode neu, um die Änderungen zu übernehmen.", - "info.common.confirm": "Bestätigen" + "info.common.codedoc": "Code-Dokumentation" } \ No newline at end of file diff --git a/l10n/bundle.l10n.en.json b/l10n/bundle.l10n.en.json index e2b8d22..3284640 100644 --- a/l10n/bundle.l10n.en.json +++ b/l10n/bundle.l10n.en.json @@ -81,6 +81,5 @@ "error.simulation.error-happen-run-command": "Error during Icarus simulation:", "info.command.structure.transform-xilinx-to-standard": "Converting Xilinx project structure to Digital IDE standard structure", "error.command.structure.not-valid-xilinx-project": "The current project is not a valid Xilinx project, the conversion failed!", - "info.command.structure.reload-vscode": "Project structure conversion completed, please restart vscode to apply the changes.", - "info.common.confirm": "Confirm" + "info.common.codedoc": "Code Documentation" } \ No newline at end of file diff --git a/l10n/bundle.l10n.ja.json b/l10n/bundle.l10n.ja.json index 8b53441..1a28725 100644 --- a/l10n/bundle.l10n.ja.json +++ b/l10n/bundle.l10n.ja.json @@ -81,6 +81,5 @@ "error.simulation.error-happen-run-command": "Icarusシミュレーション中にエラーが発生しました:", "info.command.structure.transform-xilinx-to-standard": "Xilinx プロジェクト構造を Digital IDE 標準構造に変換しています", "error.command.structure.not-valid-xilinx-project": "現在のプロジェクトは有効なXilinxプロジェクトではありません、変換に失敗しました!", - "info.command.structure.reload-vscode": "プロジェクト構造の変換が完了しました。変更を適用するために vscode を再起動してください。", - "info.common.confirm": "確認" + "info.common.codedoc": "コードドキュメント" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json index 299c638..78a78be 100644 --- a/l10n/bundle.l10n.zh-cn.json +++ b/l10n/bundle.l10n.zh-cn.json @@ -81,6 +81,5 @@ "error.simulation.error-happen-run-command": "Icarus 仿真时,出现错误:", "info.command.structure.transform-xilinx-to-standard": "正在将 Xilinx 项目结构转变为 Digital IDE 标准结构", "error.command.structure.not-valid-xilinx-project": "当前项目不是一个有效的 Xilinx 项目,转换失败!", - "info.command.structure.reload-vscode": "项目结构转换完成,请重启 vscode 使应用生效", - "info.common.confirm": "确定" + "info.common.codedoc": "代码文档" } \ No newline at end of file diff --git a/l10n/bundle.l10n.zh-tw.json b/l10n/bundle.l10n.zh-tw.json index 7d9500b..8463d8e 100644 --- a/l10n/bundle.l10n.zh-tw.json +++ b/l10n/bundle.l10n.zh-tw.json @@ -81,6 +81,5 @@ "error.simulation.error-happen-run-command": "Icarus 模擬時,出現錯誤:", "info.command.structure.transform-xilinx-to-standard": "正在將 Xilinx 專案結構轉變為 Digital IDE 標準結構", "error.command.structure.not-valid-xilinx-project": "當前專案不是一個有效的 Xilinx 專案,轉換失敗!", - "info.command.structure.reload-vscode": "專案結構轉換完成,請重新啟動 vscode 使應用生效。", - "info.common.confirm": "確定" + "info.common.codedoc": "程式碼文件" } \ No newline at end of file diff --git a/resources/dide-doc/documentation.css b/resources/dide-doc/documentation.css index c30e764..5d3b663 100644 --- a/resources/dide-doc/documentation.css +++ b/resources/dide-doc/documentation.css @@ -651,6 +651,20 @@ img { background-color: rgb(53,59,140); } +#write .source-ip-tag { + font-size: 0.85rem; + padding: 3px 4px; + border-radius: .5em; + background-color: rgb(24, 91, 149); +} + +#write .source-primitive-tag { + font-size: 0.85rem; + padding: 3px 4px; + border-radius: .5em; + background-color: rgb(108, 53, 140); +} + #write .source-unk-tag { font-size: 0.85rem; padding: 3px 4px; diff --git a/resources/dide-doc/icon.png b/resources/dide-doc/icon.png new file mode 100644 index 0000000..cec5163 Binary files /dev/null and b/resources/dide-doc/icon.png differ diff --git a/resources/dide-doc/index.html b/resources/dide-doc/index.html index 310e6ba..cb080a6 100644 --- a/resources/dide-doc/index.html +++ b/resources/dide-doc/index.html @@ -5,6 +5,7 @@ Digital IDE Document + diff --git a/resources/dide-lsp/static/xilinx/primitive.bin b/resources/dide-lsp/static/xilinx/primitive.bin index f987783..aedc7c0 100644 Binary files a/resources/dide-lsp/static/xilinx/primitive.bin and b/resources/dide-lsp/static/xilinx/primitive.bin differ diff --git a/src/function/hdlDoc/html.ts b/src/function/hdlDoc/html.ts index 77692d5..08cf36e 100644 --- a/src/function/hdlDoc/html.ts +++ b/src/function/hdlDoc/html.ts @@ -9,6 +9,7 @@ import { Count, MarkdownString, ThemeColorConfig, WavedromString } from './commo import { getRenderList, getCurrentRenderList } from './markdown'; import { hdlPath, hdlIcon, hdlFile } from '../../hdlFs'; import { ThemeType } from '../../global/enum'; +import { t } from '../../i18n'; const _cache = { css : '' @@ -227,8 +228,9 @@ export async function makeDocWebview(uri: vscode.Uri, context: vscode.ExtensionC } ); - panel.iconPath = hdlIcon.getIconConfig('documentation'); - + panel.iconPath = hdlIcon.getIconConfig('dide'); + panel.title = t('info.common.codedoc') + ': ' + fspath.basename(uri.fsPath); + const html = getWebviewContent(context, panel); if (html === undefined) { return panel; @@ -241,7 +243,7 @@ export async function makeDocWebview(uri: vscode.Uri, context: vscode.ExtensionC let filePath: string = message.filePath; if (filePath.startsWith('file://')) { filePath = filePath.slice(7); - } + } vscode.commands.executeCommand('vscode.open', vscode.Uri.file(filePath)); return; case 'do-render': diff --git a/src/function/hdlDoc/markdown.ts b/src/function/hdlDoc/markdown.ts index 2696ee1..ab80e70 100644 --- a/src/function/hdlDoc/markdown.ts +++ b/src/function/hdlDoc/markdown.ts @@ -43,15 +43,34 @@ function selectFieldValue(obj: any, subName: string, ws: string, name: string, i if (fs.existsSync(value)) { // 判断 类型 const hdlFile = hdlParam.getHdlFile(value); - if (hdlFile && hdlFile.projectType === HdlFileProjectType.RemoteLib) { - // 如果是 库 文件,做出更加自定义的字面量 - const libRelPath = value.replace(`${opeParam.extensionPath}/library/`, ''); - value = `library [${libRelPath}](file://${value})`; - } else { + if (hdlFile) { + switch (hdlFile.projectType) { + case HdlFileProjectType.RemoteLib: + // 如果是 库 文件,做出更加自定义的字面量 + const libRelPath = value.replace(`${opeParam.extensionPath}/library/`, ''); + value = `library [${libRelPath}](file://${value})`; + break; + case HdlFileProjectType.IP: + // 如果是 IP,定向到 xci 上 + const ipname = fspath.basename(value); + const xciPath = hdlPath.join(value, ipname + '.xci'); + value = `ip core [${relativePath}](file://${xciPath})`; + break; + default: + value = `project [${relativePath}](file://${value})`; + break; + } + } else { value = `project [${relativePath}](file://${value})`; } } else { - value = 'unknown ' + t('info.dide-doc.source.cannot-find'); + // 如果不存在,可能是原语 + const inst = obj as HdlInstance; + if (inst.getDoFastFileType === 'primitives') { + value = `${opeParam.prjInfo.toolChain} primitive`; + } else { + value = 'unknown ' + t('info.dide-doc.source.cannot-find'); + } } } @@ -171,14 +190,7 @@ async function getDocsFromModule(module: HdlModule): Promise { await portPP; // 判断是否为单文件 - let isSingleFile = false; - if (!opeParam.workspacePath || !fs.existsSync(opeParam.workspacePath)) { - isSingleFile = true; - } else { - const workspacePath = opeParam.workspacePath; - const modulePath = module.path; - isSingleFile = !modulePath.startsWith(workspacePath); - } + const isSingleFile = opeParam.openMode === 'file'; // param section const paramTitleIcon = ' '; @@ -227,10 +239,10 @@ async function getDocsFromModule(module: HdlModule): Promise { const depTitleIcon = ' '; md.addTitle(depTitleIcon + t('info.dide-doc.dependency'), 2); - let insts = module.getAllInstances(); + let insts: HdlInstance[] = []; // 对于单文件模式而言,未进行 instance 搜索,所以insts必然是空的 if (isSingleFile && insts.length === 0 && module.rawInstances) { - insts = module.rawInstances.map(rawInstance => new HdlInstance( + insts = module.rawInstances.map(rawInstance => new HdlInstance( rawInstance.name, rawInstance.type, undefined, @@ -240,6 +252,9 @@ async function getDocsFromModule(module: HdlModule): Promise { rawInstance.range, module )); + } else { + // 对于多文件,找出所有依赖项 + insts = [...module.getAllDependenceInstance()]; } // 根据 start 进行排序 diff --git a/src/function/lsp-client/index.ts b/src/function/lsp-client/index.ts index dc07c8c..f29a9fb 100644 --- a/src/function/lsp-client/index.ts +++ b/src/function/lsp-client/index.ts @@ -210,8 +210,10 @@ export async function activate(context: vscode.ExtensionContext, packageJson: an ); LspClient.DigitalIDE = client; + // 启动 lsp await client.start(); + // 检测配置文件变动 registerConfigurationUpdater(client, packageJson); } diff --git a/src/function/treeView/tree.ts b/src/function/treeView/tree.ts index 3db8f62..b66c0f0 100644 --- a/src/function/treeView/tree.ts +++ b/src/function/treeView/tree.ts @@ -203,6 +203,7 @@ class ModuleTreeProvider implements vscode.TreeDataProvider { // 默认选择依赖模块最多的作为 first top let firstTop: { path: string, name: string } | undefined = undefined; let maxDepSize = 0; + for (const hdlModule of topModules) { // 此处断言是因为当前的 name 和 path 是从 topModules 中提取的 diff --git a/src/hdlParser/common.ts b/src/hdlParser/common.ts index f1a48d2..340bd34 100644 --- a/src/hdlParser/common.ts +++ b/src/hdlParser/common.ts @@ -172,6 +172,7 @@ interface RawHdlInstance { interface RawHdlModule { name: string + archName: string params: HdlModuleParam[] ports: HdlModulePort[] instances: RawHdlInstance[] diff --git a/src/hdlParser/core.ts b/src/hdlParser/core.ts index 880d20a..7d169ab 100644 --- a/src/hdlParser/core.ts +++ b/src/hdlParser/core.ts @@ -205,11 +205,14 @@ class HdlParam { } else if (status === common.InstModPathStatus.Others && inst.instModPath) { dependencies.others.push(inst.instModPath); } - const instDependencies = this.getAllDependences(inst.module.path, inst.module.name); - if (instDependencies) { - dependencies.current.push(...instDependencies.current); - dependencies.include.push(...instDependencies.include); - dependencies.others.push(...instDependencies.others); + // 防止无限递归 + if (inst.module && inst.module !== module) { + const instDependencies = this.getAllDependences(inst.module.path, inst.module.name); + if (instDependencies) { + dependencies.current.push(...instDependencies.current); + dependencies.include.push(...instDependencies.include); + dependencies.others.push(...instDependencies.others); + } } } @@ -819,6 +822,59 @@ class HdlModule { return this.nameToInstances.size; } + /** + * @description 获取当前模块的所有依赖路径 + * @returns + */ + public getAllDependences(): common.HdlDependence { + const dependencies : common.HdlDependence = { + current: [], + include: [], + others: [] + }; + + for (const inst of this.getAllInstances()) { + if (!inst.module) { + continue; + } + const status = inst.instModPathStatus; + if (status === common.InstModPathStatus.Current && inst.instModPath) { + dependencies.current.push(inst.instModPath); + } else if (status === common.InstModPathStatus.Include && inst.instModPath) { + dependencies.include.push(inst.instModPath); + } else if (status === common.InstModPathStatus.Others && inst.instModPath) { + dependencies.others.push(inst.instModPath); + } + if (inst.module) { + const instDependencies = inst.module.getAllDependences(); + dependencies.current.push(...instDependencies.current); + dependencies.include.push(...instDependencies.include); + dependencies.others.push(...instDependencies.others); + } + } + + return dependencies; + } + + /** + * @description 递归获取当前模块所有依赖 + */ + public getAllDependenceInstance(): Set { + const instances = new Set(); + // 获取自身的 + for (const inst of this.nameToInstances.values()) { + console.log(inst); + instances.add(inst); + // 递归获取 inst 的 + if (inst.module) { + for (const subInst of inst.module.getAllDependenceInstance()) { + instances.add(subInst); + } + } + } + return instances; + } + public createHdlInstance(rawHdlInstance: common.RawHdlInstance): HdlInstance { const instModName = rawHdlInstance.type; @@ -1092,6 +1148,8 @@ export class HdlFile { // add to global hdlParam hdlParam.setHdlFile(this); + console.log(modules); + // make nameToModule this.nameToModule = new Map(); for (const rawHdlModule of modules) {