;
- private _controller?: SidebarViewController;
+ public controller?: SidebarViewController;
constructor(private readonly _extensionUri: vscode.Uri) {}
@@ -46,7 +46,7 @@ export class SidebarViewProvider implements vscode.WebviewViewProvider {
this._view.webview.html = this._getHtmlForWebview(webviewView.webview);
// 初始化 Controller
- this._controller = new SidebarViewController(this._extensionUri, this._view);
+ this.controller = new SidebarViewController(this._extensionUri, this._view);
}
private _getHtmlForWebview(webview: vscode.Webview): string {
@@ -58,8 +58,7 @@ export class SidebarViewProvider implements vscode.WebviewViewProvider {
const indexJsUri = webview.asWebviewUri(
vscode.Uri.joinPath(this._extensionUri, "out/sidebarView/index.js"),
);
- const openScmA =
- `` + vscode.l10n.t("open a repository") + ``;
+ const openScmA = `` + vscode.l10n.t("open a repository") + ``;
return `
@@ -81,13 +80,16 @@ export class SidebarViewProvider implements vscode.WebviewViewProvider {
/* margin: 1em 2em */;
padding: 0 2em;
}
+ a {
+ cursor: pointer;
+ }
div {
padding: 0;
}
.full-width {
width: calc(100% - 2em);
}
- .hide {
+ .hidden {
display: none;
}
vscode-button {
@@ -101,13 +103,18 @@ export class SidebarViewProvider implements vscode.WebviewViewProvider {
${vscode.l10n.t("Welcome to RVPortingTool: Make RISC-V Porting Easier!")}
+
+
${strFormat(vscode.l10n.t("Please {0} to continue"), openScmA)}
- ${vscode.l10n.t("Upload and Scan Source Code")}
-
+
+
${vscode.l10n.t("Detected repository, choose an action:")}
+
${vscode.l10n.t("Upload and Scan Source Code")}
+
+
${vscode.l10n.t("Import Code Check Report")}
-
+
${vscode.l10n.t("Export Code Check Report")}
${vscode.l10n.t("Clear Code Check Report")}
diff --git a/common/src/types/command.ts b/common/src/types/command.ts
index e6ba575..a369940 100644
--- a/common/src/types/command.ts
+++ b/common/src/types/command.ts
@@ -36,4 +36,7 @@ export class CommandID {
/** Wiki 助手:打开 Wiki 页面 */
public static wikiHelperOpenRule = "rvCodingAsst.wikiHelper.openRule";
+
+ /** 侧边栏:刷新状态 */
+ public static sidebarViewRefreshState = "rvCodingAsst.sidebarHelper.refreshState";
}
diff --git a/common/src/types/notification.ts b/common/src/types/notification.ts
index a8e6de5..f85b554 100644
--- a/common/src/types/notification.ts
+++ b/common/src/types/notification.ts
@@ -66,6 +66,9 @@ export class LSPNotificationID {
public static reportMgrCliReloadConfirm =
"rvCodingAsst.reportManager.notify.client.reloadConfirm";
+ /** 报告管理:卸载指定工作区的报告 */
+ public static reportMgrSrvUnload = "rvCodingAsst.reportManager.notify.server.unload";
+
/** 报告管理:清除所有报告 */
public static reportMgrSrvClearAll = "rvCodingAsst.reportManager.notify.server.clearAllReport";
}
diff --git a/common/src/types/sidebarView.ts b/common/src/types/sidebarView.ts
index 6210338..e79a716 100644
--- a/common/src/types/sidebarView.ts
+++ b/common/src/types/sidebarView.ts
@@ -84,47 +84,47 @@ export interface CodeNoReportMsg {
/** SidebarView 消息类型检查辅助类 */
export class SidebarViewMsgUtil {
/** 判断是否为 SidebarView 加载完毕消息 */
- public static isLoadedMsg(msg: any): msg is ViewLoadedMsg {
+ public static isViewLoadedMsg(msg: any): msg is ViewLoadedMsg {
return msg.type === "ViewLoadedMsg";
}
/** 判断是否为 SidebarView 打开文件夹消息 */
- public static isOpenSCMMsg(msg: any): msg is UserOpenSCMMsg {
+ public static isUserOpenSCMMsg(msg: any): msg is UserOpenSCMMsg {
return msg.type === "UserOpenSCMMsg";
}
/** 判断是否为 SidebarView 已打开存储库消息 */
- public static isOpenedGitRepoMsg(msg: any): msg is CodeOpenedRepoMsg {
+ public static isCodeOpenedRepoMsg(msg: any): msg is CodeOpenedRepoMsg {
return msg.type === "CodeOpenedRepoMsg";
}
/** 判断是否为 SidebarView 已关闭存储库消息 */
- public static isClosedGitRepoMsg(msg: any): msg is CodeClosedRepoMsg {
+ public static isCodeClosedRepoMsg(msg: any): msg is CodeClosedRepoMsg {
return msg.type === "CodeClosedRepoMsg";
}
/** 判断是否为 SidebarView 导入扫描报告消息 */
- public static isImportReportMsg(msg: any): msg is UserImportReportMsg {
+ public static isUserImportReportMsg(msg: any): msg is UserImportReportMsg {
return msg.type === "UserImportReportMsg";
}
/** 判断是否为 SidebarView 导出扫描报告消息 */
- public static isExportReportMsg(msg: any): msg is UserExportReportMsg {
+ public static isUserExportReportMsg(msg: any): msg is UserExportReportMsg {
return msg.type === "UserExportReportMsg";
}
/** 判断是否为 SidebarView 清除扫描报告消息 */
- public static isClearReportMsg(msg: any): msg is UserClearReportMsg {
+ public static isUserClearReportMsg(msg: any): msg is UserClearReportMsg {
return msg.type === "UserClearReportMsg";
}
/** 判断是否为 SidebarView 有扫描报告消息 */
- public static isHasReportMsg(msg: any): msg is CodeHasReportMsg {
+ public static isCodeHasReportMsg(msg: any): msg is CodeHasReportMsg {
return msg.type === "CodeHasReportMsg";
}
/** 判断是否为 SidebarView 无扫描报告消息 */
- public static isNoReportMsg(msg: any): msg is CodeNoReportMsg {
+ public static isCodeNoReportMsg(msg: any): msg is CodeNoReportMsg {
return msg.type === "CodeNoReportMsg";
}
}
diff --git a/package.json b/package.json
index d916b60..dacfcc9 100644
--- a/package.json
+++ b/package.json
@@ -80,6 +80,10 @@
{
"command": "rvCodingAsst.wikiHelper.openRule",
"title": "%rvCodingAsst.command.wikiHelper.openRule%"
+ },
+ {
+ "command": "rvCodingAsst.sidebarHelper.refreshState",
+ "title": "%rvCodingAsst.command.sidebarHelper.refreshState%"
}
],
"viewsContainers": {
diff --git a/package.nls.json b/package.nls.json
index 1bafdbd..33197bc 100644
--- a/package.nls.json
+++ b/package.nls.json
@@ -8,6 +8,7 @@
"rvCodingAsst.command.reportManager.exportReport": "RVPortingTool: Export report to file",
"rvCodingAsst.command.reportManager.clearAllReport": "RVPortingTool: Clear All Reports",
"rvCodingAsst.command.wikiHelper.openRule": "RVPortingTool: Open Rule Definition in Wiki",
+ "rvCodingAsst.command.sidebarHelper.refreshState": "RVPortingTool: Refresh Sidebar View State",
"rvCodingAsst.viewContainers.panel.title": "RVPortingTool",
"rvCodingAsst.viewContainers.activitybar.title": "RVPortingTool",
"rvCodingAsst.view.wiki.name": "RV Porting Wiki",
diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json
index a0b6f10..a418edc 100644
--- a/package.nls.zh-cn.json
+++ b/package.nls.zh-cn.json
@@ -8,6 +8,7 @@
"rvCodingAsst.command.reportManager.exportReport": "RVPortingTool: 导出报告文件",
"rvCodingAsst.command.reportManager.clearAllReport": "RVPortingTool: 清除所有报告",
"rvCodingAsst.command.wikiHelper.openRule": "RVPortingTool: 在 Wiki 中打开规则定义",
+ "rvCodingAsst.command.sidebarHelper.refreshState": "RVPortingTool: 刷新侧边栏状态",
"rvCodingAsst.viewContainers.panel.title": "RVPortingTool",
"rvCodingAsst.viewContainers.activitybar.title": "RVPortingTool",
"rvCodingAsst.view.wiki.name": "迁移知识库",
diff --git a/server/src/reportManagerServer.ts b/server/src/reportManagerServer.ts
index 7b6989c..8de6d03 100644
--- a/server/src/reportManagerServer.ts
+++ b/server/src/reportManagerServer.ts
@@ -107,6 +107,11 @@ export class ReportManagerServer {
manager.onSaveCacheAll();
});
+ // 监听通知:卸载指定工作区的报告
+ connection.onNotification(LSPNotificationID.reportMgrSrvUnload, (data) => {
+ manager.unloadWorkspacesReport(data);
+ });
+
// 监听请求:获取指定工作区的代码扫描报告元数据
connection.onRequest(
reqTypes.LSPRequestID.reportMgrGetWorkspaceMeta,
diff --git a/webview/src/sidebarView/index.ts b/webview/src/sidebarView/index.ts
index a93e0cb..e45fdc2 100644
--- a/webview/src/sidebarView/index.ts
+++ b/webview/src/sidebarView/index.ts
@@ -22,9 +22,6 @@ import * as viewTypes from "../../../common/src/types/sidebarView";
(() => {
const vscode = acquireVsCodeApi
();
- /** 全局消息响应函数表 */
- const msgHandlers: Map void> = new Map();
-
/** CSS Class 与对应的点击回调事件表 */
const onClickMap: Map void> = new Map();
@@ -58,6 +55,22 @@ import * as viewTypes from "../../../common/src/types/sidebarView";
});
};
+ const showUIElements = (clsNames: string[]) => {
+ for (const clsName of clsNames) {
+ for (const elem of document.getElementsByClassName(clsName)) {
+ elem.classList.remove("hidden");
+ }
+ }
+ };
+
+ const hideUIElements = (clsNames: string[]) => {
+ for (const clsName of clsNames) {
+ for (const elem of document.getElementsByClassName(clsName)) {
+ elem.classList.add("hidden");
+ }
+ }
+ };
+
// SidebarView 加载完毕,发送消息
window.addEventListener("load", () => {
console.debug("SidebarView Initialized, state: ", JSON.stringify(vscode.getState()));
@@ -70,8 +83,29 @@ import * as viewTypes from "../../../common/src/types/sidebarView";
window.addEventListener("message", (ev) => {
const message = ev.data;
console.info("SidebarView received message: ", message);
- if (message.type && msgHandlers.has(message.type)) {
- msgHandlers.get(message.type)!(message);
+ if (viewTypes.SidebarViewMsgUtil.isCodeOpenedRepoMsg(message)) {
+ // 已打开 SCM Repo
+ hideUIElements(["ui-no-repo"]);
+ showUIElements(["ui-has-repo"]);
+ return;
+ }
+ if (viewTypes.SidebarViewMsgUtil.isCodeClosedRepoMsg(message)) {
+ // 已关闭 SCM Repo
+ hideUIElements(["ui-has-repo"]);
+ showUIElements(["ui-no-repo"]);
+ return;
+ }
+ if (viewTypes.SidebarViewMsgUtil.isCodeNoReportMsg(message)) {
+ // 没有代码扫描报告
+ hideUIElements(["ui-has-report"]);
+ showUIElements(["ui-no-report"]);
+ return;
+ }
+ if (viewTypes.SidebarViewMsgUtil.isCodeHasReportMsg(message)) {
+ // 有代码扫描报告
+ hideUIElements(["ui-no-report"]);
+ showUIElements(["ui-has-report"]);
+ return;
}
});
@@ -79,7 +113,10 @@ import * as viewTypes from "../../../common/src/types/sidebarView";
initOnClickMap();
for (const [clsName, onClick] of onClickMap) {
for (const elem of document.getElementsByClassName(clsName)) {
- elem.addEventListener("click", onClick);
+ elem.addEventListener("click", () => {
+ console.debug(`Triggered onClick event: ${clsName}`);
+ onClick();
+ });
}
}
})();
--
Gitee
From 623984d9a94a59d0c905f89517eccf141f48c5c6 Mon Sep 17 00:00:00 2001
From: liccc
Date: Wed, 11 Sep 2024 23:01:03 +0800
Subject: [PATCH 10/17] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E6=8A=A5?=
=?UTF-8?q?=E5=91=8A=E5=8D=B8=E8=BD=BD=E5=92=8C=E6=B8=85=E9=99=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
+ 区分报告卸载和清除逻辑
---
client/src/reportManagerClient.ts | 63 +++++++++++++++++--
.../src/sidebarView/sidebarViewController.ts | 3 +
client/src/sidebarView/sidebarViewProvider.ts | 1 +
common/src/types/command.ts | 3 +
common/src/types/notification.ts | 7 ++-
common/src/types/sidebarView.ts | 11 ++++
l10n/bundle.l10n.json | 5 ++
l10n/bundle.l10n.zh-cn.json | 6 +-
package.json | 4 ++
package.nls.json | 1 +
package.nls.zh-cn.json | 1 +
server/src/reportManager.ts | 18 +++++-
server/src/reportManagerServer.ts | 60 +++++++++++++++---
webview/src/sidebarView/index.ts | 9 ++-
14 files changed, 174 insertions(+), 18 deletions(-)
diff --git a/client/src/reportManagerClient.ts b/client/src/reportManagerClient.ts
index 0a03db6..3e4989f 100644
--- a/client/src/reportManagerClient.ts
+++ b/client/src/reportManagerClient.ts
@@ -14,7 +14,7 @@
* Language Client Report Manager for RVPortingTool VSCode Extension
*
* Author: Lightning Rainstorm
- * Last Change: Sep 6, 2024
+ * Last Change: Sep 11, 2024
**************************************************************************************/
import * as lsp from "vscode-languageclient";
@@ -98,6 +98,11 @@ export class ReportManagerClient {
this._instance.saveAllReportsCache();
}),
+ // 卸载所有报告
+ vscode.commands.registerCommand(CommandID.reportMgrUnloadAllReport, () => {
+ this._instance.unloadAllReport();
+ }),
+
// 清除所有报告
vscode.commands.registerCommand(CommandID.reportMgrClearAllReport, () => {
this._instance.clearAllReport();
@@ -145,6 +150,11 @@ export class ReportManagerClient {
this._instance.onSaveError(data);
});
+ // 注册通知:报告卸载
+ client.onNotification(LSPNotificationID.reportMgrCliUnloadFinished, () => {
+ this._instance.onUnload();
+ });
+
// 发送通知:加载报告 JSON Schema
const schemaPath = context.asAbsolutePath("resources/report_schema.json");
client.sendNotification(LSPNotificationID.reportMgrSrvLoadSchema, schemaPath);
@@ -267,6 +277,13 @@ Your operations will be lost if you don't export the report manually after worki
});
}
+ /**
+ * 报告卸载
+ */
+ public onUnload() {
+ vscode.commands.executeCommand(CommandID.sidebarViewRefreshState);
+ }
+
/**
* 导入报告前选择工作区
*
@@ -373,13 +390,50 @@ Your operations will be lost if you don't export the report manually after worki
this._client.sendNotification(LSPNotificationID.reportMgrSrvSaveCacheAll);
}
+ /**
+ * 卸载所有报告(暂时性卸载,要求用户确认)
+ */
+ public unloadAllReport() {
+ const message = vscode.l10n.t("Report unload confirm");
+ const messageOptions: vscode.MessageOptions = {
+ detail: vscode.l10n.t(
+ "Are you sure to temporarily unload all loaded reports? The reports will be automatically load next time after reloading or restarting Workspace/VSCode.",
+ ),
+ modal: true,
+ };
+ const nextOptions: string[] = [];
+ const optionConfirm = vscode.l10n.t("Confirm");
+ nextOptions.push(optionConfirm);
+ vscode.window.showInformationMessage(message, messageOptions, ...nextOptions).then((value) => {
+ if (value === optionConfirm) {
+ this._doUnloadAllReport();
+ }
+ });
+ }
+
+ /**
+ * 卸载所有报告
+ */
+ private _doUnloadAllReport() {
+ const wsFolders = vscode.workspace.workspaceFolders;
+ if (!wsFolders) {
+ // 未获取到工作区文件夹
+ logger.warn("workspace folders not found when unload all report");
+ return;
+ }
+ const wsFoldersUri = wsFolders.map((wsFolder) => wsFolder.uri.toString());
+ this._client.sendNotification(LSPNotificationID.reportMgrSrvUnload, wsFoldersUri);
+ }
+
/**
* 清除所有报告(要求用户确认)
*/
public clearAllReport() {
const message = vscode.l10n.t("Report clear confirm");
const messageOptions: vscode.MessageOptions = {
- detail: vscode.l10n.t("Are you sure to unload all loaded reports?"),
+ detail: vscode.l10n.t(
+ "Are you sure to clear all loaded reports? This operation will remove it from workspace cache too!",
+ ),
modal: true,
};
const nextOptions: string[] = [];
@@ -402,9 +456,8 @@ Your operations will be lost if you don't export the report manually after worki
logger.warn("workspace folders not found when clear all report");
return;
}
- for (const wsFolder of wsFolders) {
- this._client.sendNotification(LSPNotificationID.reportMgrSrvUnload, wsFolder.uri.toString());
- }
+ const wsFoldersUri = wsFolders.map((wsFolder) => wsFolder.uri.toString());
+ this._client.sendNotification(LSPNotificationID.reportMgrSrvClear, wsFoldersUri);
}
/**
diff --git a/client/src/sidebarView/sidebarViewController.ts b/client/src/sidebarView/sidebarViewController.ts
index 9ad3457..87046ff 100644
--- a/client/src/sidebarView/sidebarViewController.ts
+++ b/client/src/sidebarView/sidebarViewController.ts
@@ -158,6 +158,9 @@ export class SidebarViewController {
} else if (viewTypes.SidebarViewMsgUtil.isUserExportReportMsg(message)) {
// WebView 请求导出报告
vscode.commands.executeCommand(CommandID.reportMgrExportReport);
+ } else if (viewTypes.SidebarViewMsgUtil.isUserUnloadReportMsg(message)) {
+ // WebView 请求卸载报告
+ vscode.commands.executeCommand(CommandID.reportMgrUnloadAllReport);
} else if (viewTypes.SidebarViewMsgUtil.isUserClearReportMsg(message)) {
// WebView 请求清除报告
vscode.commands.executeCommand(CommandID.reportMgrClearAllReport);
diff --git a/client/src/sidebarView/sidebarViewProvider.ts b/client/src/sidebarView/sidebarViewProvider.ts
index 042ff00..d09e4ff 100644
--- a/client/src/sidebarView/sidebarViewProvider.ts
+++ b/client/src/sidebarView/sidebarViewProvider.ts
@@ -116,6 +116,7 @@ export class SidebarViewProvider implements vscode.WebviewViewProvider {
${vscode.l10n.t("Export Code Check Report")}
+ ${vscode.l10n.t("Unload Code Check Report")}
${vscode.l10n.t("Clear Code Check Report")}
diff --git a/common/src/types/command.ts b/common/src/types/command.ts
index a369940..df55f33 100644
--- a/common/src/types/command.ts
+++ b/common/src/types/command.ts
@@ -28,6 +28,9 @@ export class CommandID {
/** 报告管理:导出报告(用户选择工作区) */
public static reportMgrExportReport = "rvCodingAsst.reportManager.exportReport";
+ /** 报告管理:卸载所有报告 */
+ public static reportMgrUnloadAllReport = "rvCodingAsst.reportManager.unloadAllReport";
+
/** 报告管理:清除所有报告 */
public static reportMgrClearAllReport = "rvCodingAsst.reportManager.clearAllReport";
diff --git a/common/src/types/notification.ts b/common/src/types/notification.ts
index f85b554..8d3eb57 100644
--- a/common/src/types/notification.ts
+++ b/common/src/types/notification.ts
@@ -69,6 +69,9 @@ export class LSPNotificationID {
/** 报告管理:卸载指定工作区的报告 */
public static reportMgrSrvUnload = "rvCodingAsst.reportManager.notify.server.unload";
- /** 报告管理:清除所有报告 */
- public static reportMgrSrvClearAll = "rvCodingAsst.reportManager.notify.server.clearAllReport";
+ /** 报告管理:卸载报告完成 */
+ static reportMgrCliUnloadFinished = "rvCodingAsst.reportManager.notify.client.unloadFinished";
+
+ /** 报告管理:清除指定工作区的报告 */
+ public static reportMgrSrvClear = "rvCodingAsst.reportManager.notify.server.clearAllReport";
}
diff --git a/common/src/types/sidebarView.ts b/common/src/types/sidebarView.ts
index e79a716..8e77ce3 100644
--- a/common/src/types/sidebarView.ts
+++ b/common/src/types/sidebarView.ts
@@ -63,6 +63,12 @@ export interface UserExportReportMsg {
type: "UserExportReportMsg";
}
+/** User: 卸载扫描报告消息 */
+export interface UserUnloadReportMsg {
+ /** type */
+ type: "UserUnloadReportMsg";
+}
+
/** User: 清除扫描报告消息 */
export interface UserClearReportMsg {
/** type */
@@ -113,6 +119,11 @@ export class SidebarViewMsgUtil {
return msg.type === "UserExportReportMsg";
}
+ /** 判断是否为 SidebarView 卸载扫描报告消息 */
+ public static isUserUnloadReportMsg(msg: any): msg is UserUnloadReportMsg {
+ return msg.type === "UserUnloadReportMsg";
+ }
+
/** 判断是否为 SidebarView 清除扫描报告消息 */
public static isUserClearReportMsg(msg: any): msg is UserClearReportMsg {
return msg.type === "UserClearReportMsg";
diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json
index 8abad07..46ca01e 100644
--- a/l10n/bundle.l10n.json
+++ b/l10n/bundle.l10n.json
@@ -6,6 +6,8 @@
"Architecture-related built-in macro statement block": "Architecture-related built-in macro statement block",
"Architecture-related macro in requirements": "Architecture-related macro in requirements",
"Architecture-related pre-defined macro from compiler": "Architecture-related pre-defined macro from compiler",
+ "Are you sure to clear all loaded reports? This operation will remove it from workspace cache too!": "Are you sure to clear all loaded reports? This operation will remove it from workspace cache too!",
+ "Are you sure to temporarily unload all loaded reports? The reports will be automatically load next time after reloading or restarting Workspace/VSCode.": "Are you sure to temporarily unload all loaded reports? The reports will be automatically load next time after reloading or restarting Workspace/VSCode.",
"C/C++": "C/C++",
"Clear Code Check Report": "Clear Code Check Report",
"Code Scan Report": "Code Scan Report",
@@ -33,7 +35,9 @@
"Please choose code scanning report file": "Please choose code scanning report file",
"Please open a folder as workspace before loading report": "Please open a folder as workspace before loading report",
"Please {0} to continue": "Please {0} to continue",
+ "Report clear confirm": "Report clear confirm",
"Report reloading confirm": "Report reloading confirm",
+ "Report unload confirm": "Report unload confirm",
"Retry": "Retry",
"Right-shift operation on signed integer": "Right-shift operation on signed integer",
"Save": "Save",
@@ -45,6 +49,7 @@
"The report for following workspace(s) are failed to save\n": "The report for following workspace(s) are failed to save\n",
"The workspace already contains report data! Would you like to override it?": "The workspace already contains report data! Would you like to override it?",
"Unknown reason": "Unknown reason",
+ "Unload Code Check Report": "Unload Code Check Report",
"Upload and Scan Source Code": "Upload and Scan Source Code",
"Welcome to RVPortingTool: Make RISC-V Porting Easier!": "Welcome to RVPortingTool: Make RISC-V Porting Easier!",
"X86": "X86",
diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json
index 5ae6a5f..f91a505 100644
--- a/l10n/bundle.l10n.zh-cn.json
+++ b/l10n/bundle.l10n.zh-cn.json
@@ -6,6 +6,8 @@
"Architecture-related built-in macro statement block": "架构相关内置宏语句块",
"Architecture-related macro in requirements": "依赖项名称出现架构相关内置宏",
"Architecture-related pre-defined macro from compiler": "编译器架构相关预定义宏",
+ "Are you sure to clear all loaded reports? This operation will remove it from workspace cache too!": "您确定要清除所有已加载的报告吗?此操作会同时将报告从工作区缓存中删除!",
+ "Are you sure to temporarily unload all loaded reports? The reports will be automatically load next time after reloading or restarting Workspace/VSCode.": "您确定要临时卸载所有已加载的报告吗?下次重新加载或重启 工作区/VSCode 时,报告将自动加载。",
"C/C++": "C/C++",
"Clear Code Check Report": "清除代码扫描报告",
"Code Scan Report": "代码扫描报告",
@@ -32,8 +34,9 @@
"Please choose a workspace for displaying report": "请选择报告对应的工作区",
"Please choose code scanning report file": "请选择代码扫描报告文件",
"Please open a folder as workspace before loading report": "加载报告前请先打开一个工作区",
- "Please {0} to continue": "请 {0} 后继续",
+ "Report clear confirm": "请确认是否清除所有报告",
"Report reloading confirm": "请确认是否重新加载报告数据",
+ "Report unload confirm": "请确认是否卸载所有报告",
"Retry": "重试",
"Right-shift operation on signed integer": "有符号数的右移运算",
"Save": "保存",
@@ -45,6 +48,7 @@
"The report for following workspace(s) are failed to save\n": "以下工作区的报告保存失败:\n",
"The workspace already contains report data! Would you like to override it?": "工作区已存在报告数据!请确认是否替换?",
"Unknown reason": "未知原因",
+ "Unload Code Check Report": "卸载代码扫描报告",
"Upload and Scan Source Code": "上传并扫描源码",
"Welcome to RVPortingTool: Make RISC-V Porting Easier!": "欢迎使用睿迁工具:让 RISC-V 移植更简单!",
"X86": "X86",
diff --git a/package.json b/package.json
index dacfcc9..3dd1a6f 100644
--- a/package.json
+++ b/package.json
@@ -69,6 +69,10 @@
"command": "rvCodingAsst.reportManager.exportReport",
"title": "%rvCodingAsst.command.reportManager.exportReport%"
},
+ {
+ "command": "rvCodingAsst.reportManager.unloadAllReport",
+ "title": "%rvCodingAsst.command.reportManager.unloadAllReport%"
+ },
{
"command": "rvCodingAsst.reportManager.clearAllReport",
"title": "%rvCodingAsst.command.reportManager.clearAllReport%"
diff --git a/package.nls.json b/package.nls.json
index 33197bc..6528e30 100644
--- a/package.nls.json
+++ b/package.nls.json
@@ -6,6 +6,7 @@
"rvCodingAsst.command.reportManager.importReport": "RVPortingTool: Load Code Check Report",
"rvCodingAsst.command.reportManager.saveAllReportsCache": "RVPortingTool: Save All Reports Cache to Workspace",
"rvCodingAsst.command.reportManager.exportReport": "RVPortingTool: Export report to file",
+ "rvCodingAsst.command.reportManager.unloadAllReport": "RVPortingTool: Unload All Reports",
"rvCodingAsst.command.reportManager.clearAllReport": "RVPortingTool: Clear All Reports",
"rvCodingAsst.command.wikiHelper.openRule": "RVPortingTool: Open Rule Definition in Wiki",
"rvCodingAsst.command.sidebarHelper.refreshState": "RVPortingTool: Refresh Sidebar View State",
diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json
index a418edc..f242591 100644
--- a/package.nls.zh-cn.json
+++ b/package.nls.zh-cn.json
@@ -6,6 +6,7 @@
"rvCodingAsst.command.reportManager.importReport": "RVPortingTool: 加载代码扫描报告",
"rvCodingAsst.command.reportManager.saveAllReportsCache": "RVPortingTool: 保存所有报告 (缓存到工作区)",
"rvCodingAsst.command.reportManager.exportReport": "RVPortingTool: 导出报告文件",
+ "rvCodingAsst.command.reportManager.unloadAllReport": "RVPortingTool: 卸载所有报告",
"rvCodingAsst.command.reportManager.clearAllReport": "RVPortingTool: 清除所有报告",
"rvCodingAsst.command.wikiHelper.openRule": "RVPortingTool: 在 Wiki 中打开规则定义",
"rvCodingAsst.command.sidebarHelper.refreshState": "RVPortingTool: 刷新侧边栏状态",
diff --git a/server/src/reportManager.ts b/server/src/reportManager.ts
index c4e6b80..4344429 100644
--- a/server/src/reportManager.ts
+++ b/server/src/reportManager.ts
@@ -288,6 +288,7 @@ export class ReportManager {
* @param workspaceUri 工作区路径
*/
public unloadReport(workspaceUri: string): ReportMgrSaveError | undefined {
+ logger.info(`unloading report for: ${workspaceUri}`);
const currentMeta = this._reportMetaMap.get(workspaceUri);
if (currentMeta) {
const res = this.saveReportCache(currentMeta);
@@ -298,7 +299,22 @@ export class ReportManager {
return res;
}
this._reportMetaMap.delete(workspaceUri);
- logger.info("unloadReport: ".concat(workspaceUri));
+ logger.info("unloaded report for workspace: ".concat(workspaceUri));
+ }
+ return;
+ }
+
+ /**
+ * 清除报告数据
+ *
+ * @param workspaceUri 工作区路径
+ */
+ public clearReport(workspaceUri: string) {
+ logger.info(`Clearing report for: ${workspaceUri}`);
+ const cacheUri = URI.file(this.getReportCachePath(workspaceUri));
+ if (fs.existsSync(cacheUri.fsPath)) {
+ fs.unlinkSync(cacheUri.fsPath);
+ this._reportMetaMap.delete(workspaceUri);
}
return;
}
diff --git a/server/src/reportManagerServer.ts b/server/src/reportManagerServer.ts
index 8de6d03..8e7399c 100644
--- a/server/src/reportManagerServer.ts
+++ b/server/src/reportManagerServer.ts
@@ -15,7 +15,7 @@
*
* Author: Lightning Rainstorm
* liccc
- * Last Change: Sep 6, 2024
+ * Last Change: Sep 11, 2024
**************************************************************************************/
import * as lsp from "vscode-languageserver/node";
@@ -108,10 +108,15 @@ export class ReportManagerServer {
});
// 监听通知:卸载指定工作区的报告
- connection.onNotification(LSPNotificationID.reportMgrSrvUnload, (data) => {
+ connection.onNotification(LSPNotificationID.reportMgrSrvUnload, (data: lsp.URI | lsp.URI[]) => {
manager.unloadWorkspacesReport(data);
});
+ // 监听通知:清除指定工作区的报告
+ connection.onNotification(LSPNotificationID.reportMgrSrvClear, (data: lsp.URI | lsp.URI[]) => {
+ manager.clearWorkspacesReport(data);
+ });
+
// 监听请求:获取指定工作区的代码扫描报告元数据
connection.onRequest(
reqTypes.LSPRequestID.reportMgrGetWorkspaceMeta,
@@ -298,16 +303,18 @@ export class ReportManagerServer {
*
* @param workspace 工作区路径
*/
- public unloadWorkspacesReport(workspace: lsp.WorkspaceFolder | lsp.WorkspaceFolder[]) {
- let workspaces: lsp.WorkspaceFolder[] = [];
- const failedArr: lsp.WorkspaceFolder[] = [];
+ public unloadWorkspacesReport(
+ workspace: lsp.WorkspaceFolder | lsp.WorkspaceFolder[] | lsp.URI | lsp.URI[],
+ ) {
+ let workspaces: lsp.URI[] = [];
+ const failedArr: lsp.URI[] = [];
if (Array.isArray(workspace)) {
- workspaces.concat(workspace);
+ workspaces = workspace.map((w) => (lsp.URI.is(w) ? w : w.uri));
} else {
- workspaces.push(workspace);
+ workspaces.push(lsp.URI.is(workspace) ? workspace : workspace.uri);
}
for (let folder of workspaces) {
- const res = this._reportManager.unloadReport(folder.uri.toString());
+ const res = this._reportManager.unloadReport(folder.toString());
if (res) {
failedArr.push(folder);
}
@@ -315,6 +322,37 @@ export class ReportManagerServer {
if (failedArr.length > 0) {
this._connection.sendNotification(LSPNotificationID.reportMgrCliSaveError, failedArr);
}
+ // 刷新诊断,并通知客户端报告已卸载
+ this.refreshDiagnostics();
+ this._connection.sendNotification(LSPNotificationID.reportMgrCliUnloadFinished);
+ return failedArr.length;
+ }
+
+ /**
+ * 清除指定工作区的报告数据
+ *
+ * @param workspace 工作区路径
+ */
+ public clearWorkspacesReport(
+ workspace: lsp.WorkspaceFolder | lsp.WorkspaceFolder[] | lsp.URI | lsp.URI[],
+ ) {
+ let workspaces: lsp.URI[] = [];
+ const failedArr: lsp.URI[] = [];
+ if (Array.isArray(workspace)) {
+ workspaces = workspace.map((w) => (lsp.URI.is(w) ? w : w.uri));
+ } else {
+ workspaces.push(lsp.URI.is(workspace) ? workspace : workspace.uri);
+ }
+ for (let folder of workspaces) {
+ try {
+ this._reportManager.clearReport(folder.toString());
+ } catch (e) {
+ failedArr.push(folder);
+ }
+ }
+ // 刷新诊断,并通知客户端报告已卸载
+ this.refreshDiagnostics();
+ this._connection.sendNotification(LSPNotificationID.reportMgrCliUnloadFinished);
return failedArr.length;
}
@@ -335,6 +373,12 @@ export class ReportManagerServer {
const docUri = textDocument.uri;
const reportMeta = this._reportManager.getReportMeta(docUri);
if (!reportMeta) {
+ // 清空当前所有报告
+ await this._connection.sendDiagnostics({
+ uri: docUri.toString(),
+ version: 1,
+ diagnostics: [],
+ });
return;
}
const settings =
diff --git a/webview/src/sidebarView/index.ts b/webview/src/sidebarView/index.ts
index e45fdc2..4b1b44b 100644
--- a/webview/src/sidebarView/index.ts
+++ b/webview/src/sidebarView/index.ts
@@ -14,7 +14,7 @@
* Client Sidebar View WebView Script for RVPortingTool VSCode Extension
*
* Author: Lightning Rainstorm
- * Last Change: Sep 10, 2024
+ * Last Change: Sep 11, 2024
**************************************************************************************/
import * as viewTypes from "../../../common/src/types/sidebarView";
@@ -47,6 +47,13 @@ import * as viewTypes from "../../../common/src/types/sidebarView";
});
});
+ // cmd-unload-report: 卸载代码扫描报告
+ onClickMap.set("cmd-unload-report", () => {
+ vscode.postMessage({
+ type: "UserUnloadReportMsg",
+ });
+ });
+
// cmd-clear-report: 清除代码扫描报告
onClickMap.set("cmd-clear-report", () => {
vscode.postMessage({
--
Gitee
From c28c728b05042d0ece14aaf6ff707f92f33be02b Mon Sep 17 00:00:00 2001
From: liccc
Date: Wed, 11 Sep 2024 23:02:17 +0800
Subject: [PATCH 11/17] =?UTF-8?q?enhance:=20=E4=BE=A7=E8=BE=B9=E6=A0=8F?=
=?UTF-8?q?=E6=96=87=E5=AD=97=E5=92=8C=E5=AD=98=E5=82=A8=E5=BA=93=E6=A3=80?=
=?UTF-8?q?=E6=B5=8B=E6=9D=A1=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
+ 优化侧边栏文字提示
+ 增加存储库自动检测条件
---
client/src/sidebarView/sidebarViewController.ts | 12 ++++++++++++
client/src/sidebarView/sidebarViewProvider.ts | 4 ++--
l10n/bundle.l10n.json | 3 ++-
l10n/bundle.l10n.zh-cn.json | 2 ++
4 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/client/src/sidebarView/sidebarViewController.ts b/client/src/sidebarView/sidebarViewController.ts
index 87046ff..3617441 100644
--- a/client/src/sidebarView/sidebarViewController.ts
+++ b/client/src/sidebarView/sidebarViewController.ts
@@ -129,6 +129,18 @@ export class SidebarViewController {
gitApi.onDidChangeState((state) => {
if (state === "initialized") {
logger.info(`Git extension initialized`);
+
+ // 注册回调事件
+ gitApi.onDidOpenRepository((_) => {
+ logger.info(`onDidOpenRepository triggered`);
+ this._view?.webview.postMessage(openedMsg);
+ });
+ gitApi.onDidCloseRepository((_) => {
+ logger.info(`onDidCloseRepository triggered`);
+ this._view?.webview.postMessage(closedMsg);
+ });
+
+ // 主动检查一次
this._checkIsSCMRepoOpened();
}
});
diff --git a/client/src/sidebarView/sidebarViewProvider.ts b/client/src/sidebarView/sidebarViewProvider.ts
index d09e4ff..260e9b6 100644
--- a/client/src/sidebarView/sidebarViewProvider.ts
+++ b/client/src/sidebarView/sidebarViewProvider.ts
@@ -105,10 +105,10 @@ export class SidebarViewProvider implements vscode.WebviewViewProvider {
${vscode.l10n.t("Welcome to RVPortingTool: Make RISC-V Porting Easier!")}
-
${strFormat(vscode.l10n.t("Please {0} to continue"), openScmA)}
+
${strFormat(vscode.l10n.t("Please {0} to scan code"), openScmA)}
-
${vscode.l10n.t("Detected repository, choose an action:")}
+
${vscode.l10n.t("Detected repository, you can scan code now")}
${vscode.l10n.t("Upload and Scan Source Code")}
diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json
index 46ca01e..a6f1d0b 100644
--- a/l10n/bundle.l10n.json
+++ b/l10n/bundle.l10n.json
@@ -12,6 +12,7 @@
"Clear Code Check Report": "Clear Code Check Report",
"Code Scan Report": "Code Scan Report",
"Confirm": "Confirm",
+ "Detected repository, you can scan code now": "Detected repository, you can scan code now",
"Export Code Check Report": "Export Code Check Report",
"Failed to communicate with Git extension. RVPortingTool requires Git extension to work properly.": "Failed to communicate with Git extension. RVPortingTool requires Git extension to work properly.",
"Failed to load report": "Failed to load report",
@@ -34,7 +35,7 @@
"Please choose a workspace for displaying report": "Please choose a workspace for displaying report",
"Please choose code scanning report file": "Please choose code scanning report file",
"Please open a folder as workspace before loading report": "Please open a folder as workspace before loading report",
- "Please {0} to continue": "Please {0} to continue",
+ "Please {0} to scan code": "Please {0} to scan code",
"Report clear confirm": "Report clear confirm",
"Report reloading confirm": "Report reloading confirm",
"Report unload confirm": "Report unload confirm",
diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json
index f91a505..92c78c7 100644
--- a/l10n/bundle.l10n.zh-cn.json
+++ b/l10n/bundle.l10n.zh-cn.json
@@ -12,6 +12,7 @@
"Clear Code Check Report": "清除代码扫描报告",
"Code Scan Report": "代码扫描报告",
"Confirm": "确认",
+ "Detected repository, you can scan code now": "已检测到存储库,可使用代码扫描功能",
"Export Code Check Report": "导出代码扫描报告",
"Failed to communicate with Git extension. RVPortingTool requires Git extension to work properly.": "无法与 Git 扩展通信。睿迁工具需要使用 Git 扩展才能正常工作。",
"Failed to load report": "加载报告失败",
@@ -34,6 +35,7 @@
"Please choose a workspace for displaying report": "请选择报告对应的工作区",
"Please choose code scanning report file": "请选择代码扫描报告文件",
"Please open a folder as workspace before loading report": "加载报告前请先打开一个工作区",
+ "Please {0} to scan code": "请 {0} 以使用代码扫描功能",
"Report clear confirm": "请确认是否清除所有报告",
"Report reloading confirm": "请确认是否重新加载报告数据",
"Report unload confirm": "请确认是否卸载所有报告",
--
Gitee
From fa1743a1bda5fcbb9117c77e0f085c6dfc1c1f02 Mon Sep 17 00:00:00 2001
From: liccc
Date: Wed, 11 Sep 2024 23:33:18 +0800
Subject: [PATCH 12/17] =?UTF-8?q?style:=20=E6=A0=BC=E5=BC=8F=E5=8C=96?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.vscode/extensions.json | 3 ++-
.vscode/settings.json | 16 +++++++++++++---
client/src/extension.ts | 4 ++--
client/src/reportManagerClient.ts | 8 ++++----
client/src/sidebarHelper.ts | 4 ++--
client/src/sidebarView/sidebarViewController.ts | 6 +++---
client/src/sidebarView/sidebarViewProvider.ts | 2 +-
client/src/test/suite/index.ts | 4 ++--
client/src/types/git.d.ts | 2 +-
client/src/utils/log.ts | 2 +-
client/src/wikiHelper.ts | 4 ++--
client/src/wikiView/wikiViewProvider.ts | 6 +-----
common/src/types/reportMeta.ts | 2 +-
l10n/bundle.l10n.json | 2 +-
server/src/docCacheManager.ts | 3 +--
server/src/docSettingManager.ts | 2 +-
server/src/reportManager.ts | 11 ++++++-----
server/src/reportManagerServer.ts | 17 ++++++++---------
server/src/reportToDiagnostic.ts | 6 +++---
server/src/reportTransformer.ts | 7 +++----
server/src/server.ts | 6 +++---
server/src/types/reportMeta.ts | 2 +-
webview/src/wikiView/initUI.ts | 2 --
webview/src/wikiView/main.ts | 4 ++--
24 files changed, 64 insertions(+), 61 deletions(-)
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 9db6943..1e3e6a4 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -10,6 +10,7 @@
"ms-python.python",
"rioj7.commandOnAllFiles",
"nsoult.typescript-imports-sort",
- "connor4312.esbuild-problem-matchers"
+ "connor4312.esbuild-problem-matchers",
+ "ryuta46.multi-command"
]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 55fe7ab..8bd40f4 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -14,6 +14,10 @@
"typescript.preferences.quoteStyle": "single",
// 保存时自动格式化文件
"editor.formatOnSave": true,
+ "editor.codeActionsOnSave": {
+ "source.sortImports": "explicit",
+ "source.removeUnusedImports": "explicit"
+ },
// 使用 prettier 作为首选格式化工具
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[markdown]": {
@@ -36,10 +40,16 @@
"tcse",
"Upto"
],
+ "multiCommand.commands": [
+ {
+ "command": "multiCommand.tsFormat",
+ "sequence": ["workbench.action.files.save"]
+ }
+ ],
"commandOnAllFiles.commands": {
- "Typescript Import Sort": {
- "command": "extension.typescriptImportsSort",
- "includeFileExtensions": [".ts"]
+ "Format Typescript": {
+ "command": "multiCommand.tsFormat",
+ "includeFileExtensions": [".ts", ".tsx"]
}
},
"editor.tabSize": 2,
diff --git a/client/src/extension.ts b/client/src/extension.ts
index 237d078..53b90a5 100644
--- a/client/src/extension.ts
+++ b/client/src/extension.ts
@@ -19,7 +19,6 @@
import * as path from "path";
import * as vscode from "vscode";
-import { ClientLogger } from "./utils/log";
import {
LanguageClient,
LanguageClientOptions,
@@ -27,8 +26,9 @@ import {
TransportKind,
} from "vscode-languageclient/node";
import { ReportManagerClient } from "./reportManagerClient";
-import { WikiHelper } from "./wikiHelper";
import { SidebarHelper } from "./sidebarHelper";
+import { ClientLogger } from "./utils/log";
+import { WikiHelper } from "./wikiHelper";
// 全局 Language Client
let client: LanguageClient;
diff --git a/client/src/reportManagerClient.ts b/client/src/reportManagerClient.ts
index 3e4989f..cdef243 100644
--- a/client/src/reportManagerClient.ts
+++ b/client/src/reportManagerClient.ts
@@ -17,19 +17,19 @@
* Last Change: Sep 11, 2024
**************************************************************************************/
-import * as lsp from "vscode-languageclient";
import * as vscode from "vscode";
-import { checkerRules } from "./types/checkerRules";
-import { ClientLogger } from "./utils/log";
+import * as lsp from "vscode-languageclient";
import { CommandID } from "../../common/src/types/command";
import { LSPNotificationID } from "../../common/src/types/notification";
-import * as lspRequestTypes from "../../common/src/types/request";
import {
ReportMgrLoadError,
ReportMgrLoadParams,
ReportMgrSaveError,
ReportMgrSaveParams,
} from "../../common/src/types/reportManager";
+import * as lspRequestTypes from "../../common/src/types/request";
+import { checkerRules } from "./types/checkerRules";
+import { ClientLogger } from "./utils/log";
import path = require("path");
/** 模块日志记录器 */
diff --git a/client/src/sidebarHelper.ts b/client/src/sidebarHelper.ts
index ee06426..0fd3668 100644
--- a/client/src/sidebarHelper.ts
+++ b/client/src/sidebarHelper.ts
@@ -18,9 +18,9 @@
**************************************************************************************/
import * as vscode from "vscode";
-import { ClientLogger } from "./utils/log";
-import { SidebarViewProvider } from "./sidebarView/sidebarViewProvider";
import { CommandID } from "../../common/src/types/command";
+import { SidebarViewProvider } from "./sidebarView/sidebarViewProvider";
+import { ClientLogger } from "./utils/log";
const logger = ClientLogger.getLogger("WikiHelper");
diff --git a/client/src/sidebarView/sidebarViewController.ts b/client/src/sidebarView/sidebarViewController.ts
index 3617441..093eb24 100644
--- a/client/src/sidebarView/sidebarViewController.ts
+++ b/client/src/sidebarView/sidebarViewController.ts
@@ -18,12 +18,12 @@
**************************************************************************************/
import * as vscode from "vscode";
+import { CommandID } from "../../../common/src/types/command";
+import * as viewTypes from "../../../common/src/types/sidebarView";
+import { ReportManagerClient } from "../reportManagerClient";
import * as gitTypes from "../types/git";
import { ClientLogger } from "../utils/log";
-import * as viewTypes from "../../../common/src/types/sidebarView";
-import { CommandID } from "../../../common/src/types/command";
import strFormat = require("string-format");
-import { ReportManagerClient } from "../reportManagerClient";
const logger: ClientLogger = ClientLogger.getLogger("client.SidebarViewController");
diff --git a/client/src/sidebarView/sidebarViewProvider.ts b/client/src/sidebarView/sidebarViewProvider.ts
index 260e9b6..5082f3e 100644
--- a/client/src/sidebarView/sidebarViewProvider.ts
+++ b/client/src/sidebarView/sidebarViewProvider.ts
@@ -19,8 +19,8 @@
import * as vscode from "vscode";
import * as viewTypes from "../../../common/src/types/sidebarView";
-import strFormat = require("string-format");
import { SidebarViewController } from "./sidebarViewController";
+import strFormat = require("string-format");
export class SidebarViewProvider implements vscode.WebviewViewProvider {
public static readonly viewType = "rvCodingAsst.view.sidebar";
diff --git a/client/src/test/suite/index.ts b/client/src/test/suite/index.ts
index 36adc57..367c5dd 100644
--- a/client/src/test/suite/index.ts
+++ b/client/src/test/suite/index.ts
@@ -18,9 +18,9 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
-import * as path from "path";
-import * as Mocha from "mocha";
import { glob } from "glob";
+import * as Mocha from "mocha";
+import * as path from "path";
export function run(): Promise {
// Create the mocha test
diff --git a/client/src/types/git.d.ts b/client/src/types/git.d.ts
index f17fca6..63b8fe0 100644
--- a/client/src/types/git.d.ts
+++ b/client/src/types/git.d.ts
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { Uri, Event, Disposable, ProviderResult, Command, CancellationToken } from "vscode";
+import { CancellationToken, Command, Disposable, Event, ProviderResult, Uri } from "vscode";
export { ProviderResult } from "vscode";
export interface Git {
diff --git a/client/src/utils/log.ts b/client/src/utils/log.ts
index 1dff08d..444d0c1 100644
--- a/client/src/utils/log.ts
+++ b/client/src/utils/log.ts
@@ -18,8 +18,8 @@
**************************************************************************************/
import * as log4js from "log4js";
-import * as lsp from "vscode-languageclient";
import * as vscode from "vscode";
+import * as lsp from "vscode-languageclient";
/** Log levels */
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
diff --git a/client/src/wikiHelper.ts b/client/src/wikiHelper.ts
index dece5ea..c74a453 100644
--- a/client/src/wikiHelper.ts
+++ b/client/src/wikiHelper.ts
@@ -17,10 +17,10 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
-import * as lsp from "vscode-languageclient/node";
import * as vscode from "vscode";
-import { ClientLogger } from "./utils/log";
+import * as lsp from "vscode-languageclient/node";
import { CommandID } from "../../common/src/types/command";
+import { ClientLogger } from "./utils/log";
import { WikiViewProvider } from "./wikiView/wikiViewProvider";
const logger = ClientLogger.getLogger("WikiHelper");
diff --git a/client/src/wikiView/wikiViewProvider.ts b/client/src/wikiView/wikiViewProvider.ts
index 963971c..e471ff1 100644
--- a/client/src/wikiView/wikiViewProvider.ts
+++ b/client/src/wikiView/wikiViewProvider.ts
@@ -19,12 +19,8 @@
import * as fs from "fs";
import * as vscode from "vscode";
+import { WikiViewApplyMarkdownMsg, WikiViewMsgUtil } from "../../../common/src/types/wikiView";
import { checkerRules } from "../types/checkerRules";
-import {
- WikiViewApplyMarkdownMsg,
- WikiViewLoadedMsg,
- WikiViewMsgUtil,
-} from "../../../common/src/types/wikiView";
export class WikiViewProvider implements vscode.WebviewViewProvider {
public static readonly viewType = "rvCodingAsst.view.wiki";
diff --git a/common/src/types/reportMeta.ts b/common/src/types/reportMeta.ts
index 72fa1e7..e5e925c 100644
--- a/common/src/types/reportMeta.ts
+++ b/common/src/types/reportMeta.ts
@@ -17,8 +17,8 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
-import { IReport } from "./report";
import { URI } from "vscode-uri";
+import { IReport } from "./report";
/** 代码扫描报告元数据类 */
diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json
index a6f1d0b..4cfd7da 100644
--- a/l10n/bundle.l10n.json
+++ b/l10n/bundle.l10n.json
@@ -76,4 +76,4 @@
"shifting": "shifting",
"signed integer": "signed integer",
"system call": "system call"
-}
\ No newline at end of file
+}
diff --git a/server/src/docCacheManager.ts b/server/src/docCacheManager.ts
index 0ec2a0a..7df4059 100644
--- a/server/src/docCacheManager.ts
+++ b/server/src/docCacheManager.ts
@@ -17,10 +17,9 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
+import { TextDocument, TextDocumentContentChangeEvent } from "vscode-languageserver-textdocument";
import * as lsp from "vscode-languageserver/node";
import { ServerLogger } from "./utils/log";
-import { TextDocument, TextDocumentContentChangeEvent } from "vscode-languageserver-textdocument";
-import { TextDocumentChangeEvent } from "vscode";
const logger = ServerLogger.getLogger("DocumentsCacheManager");
diff --git a/server/src/docSettingManager.ts b/server/src/docSettingManager.ts
index bc61e93..9646186 100644
--- a/server/src/docSettingManager.ts
+++ b/server/src/docSettingManager.ts
@@ -17,10 +17,10 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
+import { TextDocument } from "vscode-languageserver-textdocument";
import * as lsp from "vscode-languageserver/node";
import { ClientCapabilities } from "./types/clientCapabilities";
import { ServerLogger } from "./utils/log";
-import { TextDocument } from "vscode-languageserver-textdocument";
/** Logger */
const logger = ServerLogger.getLogger("documentsSettingManager");
diff --git a/server/src/reportManager.ts b/server/src/reportManager.ts
index 4344429..2f2e1a4 100644
--- a/server/src/reportManager.ts
+++ b/server/src/reportManager.ts
@@ -18,20 +18,21 @@
* Last Change: Sep 11, 2024
**************************************************************************************/
+import Ajv, * as ajv from "ajv";
import * as fs from "fs";
import * as mkdirp from "mkdirp";
+import { URI } from "vscode-uri";
import { IReport } from "../../common/src/types/report";
-import { ReportMeta } from "../../common/src/types/reportMeta";
import {
ReportMgrLoadError,
ReportMgrLoadErrorType,
+ ReportMgrLoadParams,
ReportMgrSaveError,
+ ReportMgrSaveParams,
} from "../../common/src/types/reportManager";
-import { ReportMgrLoadParams, ReportMgrSaveParams } from "../../common/src/types/reportManager";
-import { ServerLogger } from "./utils/log";
+import { ReportMeta } from "../../common/src/types/reportMeta";
import { TextDocChangeParams, updateReportByTextDocumentChange } from "./reportTransformer";
-import { URI } from "vscode-uri";
-import Ajv, * as ajv from "ajv";
+import { ServerLogger } from "./utils/log";
import path = require("path");
import strFormat = require("string-format");
diff --git a/server/src/reportManagerServer.ts b/server/src/reportManagerServer.ts
index 8e7399c..f22138b 100644
--- a/server/src/reportManagerServer.ts
+++ b/server/src/reportManagerServer.ts
@@ -18,24 +18,23 @@
* Last Change: Sep 11, 2024
**************************************************************************************/
+import { TextDocument } from "vscode-languageserver-textdocument";
import * as lsp from "vscode-languageserver/node";
-import { ClientCapabilities } from "./types/clientCapabilities";
-import { DocumentsSettingManager } from "./docSettingManager";
+import { URI } from "vscode-uri";
+import { RVCodingAsstConfig } from "../../common/src/types/extConfig";
import { LSPNotificationID } from "../../common/src/types/notification";
-import { refreshDocumentDiagnostics as refreshDocumentDiagnostics } from "./reportToDiagnostic";
-import { ReportManager } from "./reportManager";
import {
ReportMgrLoadParams,
ReportMgrSaveError,
ReportMgrSaveParams,
} from "../../common/src/types/reportManager";
-import { RVCodingAsstConfig } from "../../common/src/types/extConfig";
+import * as reqTypes from "../../common/src/types/request";
+import { DocumentsSettingManager } from "./docSettingManager";
+import { ReportManager } from "./reportManager";
+import { refreshDocumentDiagnostics } from "./reportToDiagnostic";
+import { ClientCapabilities } from "./types/clientCapabilities";
import { ServerLogger } from "./utils/log";
-import { TextDocChangeParams } from "./reportTransformer";
-import { TextDocument } from "vscode-languageserver-textdocument";
-import { URI } from "vscode-uri";
import strFormat = require("string-format");
-import * as reqTypes from "../../common/src/types/request";
const logger = ServerLogger.getLogger("reportMgrServer");
diff --git a/server/src/reportToDiagnostic.ts b/server/src/reportToDiagnostic.ts
index 51b71bd..e7b5571 100644
--- a/server/src/reportToDiagnostic.ts
+++ b/server/src/reportToDiagnostic.ts
@@ -19,11 +19,11 @@
import * as lsp from "vscode-languageserver";
import * as TextDoc from "vscode-languageserver-textdocument";
+import { URI } from "vscode-uri";
import { CommandID } from "../../common/src/types/command";
-import { LSPRequestID } from "../../common/src/types/request";
-import { ReportMeta } from "../../common/src/types/reportMeta";
import { RVCodingAsstConfig } from "../../common/src/types/extConfig";
-import { URI } from "vscode-uri";
+import { ReportMeta } from "../../common/src/types/reportMeta";
+import { LSPRequestID } from "../../common/src/types/request";
import path = require("path");
interface RuleInfo {
diff --git a/server/src/reportTransformer.ts b/server/src/reportTransformer.ts
index 7267142..6064793 100644
--- a/server/src/reportTransformer.ts
+++ b/server/src/reportTransformer.ts
@@ -17,13 +17,12 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
-import * as LSPTypes from "vscode-languageserver-types";
import * as TextDoc from "vscode-languageserver-textdocument";
-import { DocumentsCacheManager } from "./docCacheManager";
+import * as LSPTypes from "vscode-languageserver-types";
import { ReportMeta } from "../../common/src/types/reportMeta";
-import { ServerLogger } from "./utils/log";
-import { SourceRange } from "../../common/src/types/report";
import { SourceRangeUtils } from "../../common/src/utils/sourceRangeUtils";
+import { DocumentsCacheManager } from "./docCacheManager";
+import { ServerLogger } from "./utils/log";
export interface TextDocChangeParams {
document: TextDoc.TextDocument;
diff --git a/server/src/server.ts b/server/src/server.ts
index 101254b..0defe3b 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -17,14 +17,14 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
+import { TextDocument } from "vscode-languageserver-textdocument";
import * as lsp from "vscode-languageserver/node";
-import { ClientCapabilities } from "./types/clientCapabilities";
+import { RVCodingAsstConfig } from "../../common/src/types/extConfig";
import { DocumentsCacheManager } from "./docCacheManager";
import { DocumentsSettingManager } from "./docSettingManager";
import { ReportManagerServer } from "./reportManagerServer";
-import { RVCodingAsstConfig } from "../../common/src/types/extConfig";
+import { ClientCapabilities } from "./types/clientCapabilities";
import { ServerLogger } from "./utils/log";
-import { TextDocument } from "vscode-languageserver-textdocument";
// Language Server 与客户端的全局连接
const connection = lsp.createConnection(lsp.ProposedFeatures.all);
diff --git a/server/src/types/reportMeta.ts b/server/src/types/reportMeta.ts
index 3404c6c..1209c8a 100644
--- a/server/src/types/reportMeta.ts
+++ b/server/src/types/reportMeta.ts
@@ -17,8 +17,8 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
-import { IReport } from "../../../common/src/types/report";
import { URI } from "vscode-uri";
+import { IReport } from "../../../common/src/types/report";
/** 代码扫描报告元数据类 */
diff --git a/webview/src/wikiView/initUI.ts b/webview/src/wikiView/initUI.ts
index b35cff1..a9047ef 100644
--- a/webview/src/wikiView/initUI.ts
+++ b/webview/src/wikiView/initUI.ts
@@ -18,8 +18,6 @@
**************************************************************************************/
import {
- Checkbox,
- DataGrid,
provideVSCodeDesignSystem,
vsCodeBadge,
vsCodeButton,
diff --git a/webview/src/wikiView/main.ts b/webview/src/wikiView/main.ts
index 659d08d..43a3484 100644
--- a/webview/src/wikiView/main.ts
+++ b/webview/src/wikiView/main.ts
@@ -17,9 +17,9 @@
* Last Change: Sep 6, 2024
**************************************************************************************/
-import { initMDTransformer } from "./mdTransformer";
-import { initUI } from "./initUI";
import { WikiViewLoadedMsg } from "../../../common/src/types/wikiView";
+import { initUI } from "./initUI";
+import { initMDTransformer } from "./mdTransformer";
import { WikiViewState } from "./state";
const vscode = acquireVsCodeApi();
--
Gitee
From ef4f6ba82ca268e4f515cbf6a8f94e2a6c9dc11a Mon Sep 17 00:00:00 2001
From: liccc
Date: Thu, 12 Sep 2024 00:36:10 +0800
Subject: [PATCH 13/17] =?UTF-8?q?refactor:=20=E8=A7=A3=E8=80=A6=20GitUtili?=
=?UTF-8?q?ty?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/sidebarView/sidebarViewController.ts | 69 ++++----------
client/src/utils/git.ts | 92 +++++++++++++++++++
2 files changed, 110 insertions(+), 51 deletions(-)
create mode 100644 client/src/utils/git.ts
diff --git a/client/src/sidebarView/sidebarViewController.ts b/client/src/sidebarView/sidebarViewController.ts
index 093eb24..6440935 100644
--- a/client/src/sidebarView/sidebarViewController.ts
+++ b/client/src/sidebarView/sidebarViewController.ts
@@ -21,7 +21,7 @@ import * as vscode from "vscode";
import { CommandID } from "../../../common/src/types/command";
import * as viewTypes from "../../../common/src/types/sidebarView";
import { ReportManagerClient } from "../reportManagerClient";
-import * as gitTypes from "../types/git";
+import { GitUtility } from "../utils/git";
import { ClientLogger } from "../utils/log";
import strFormat = require("string-format");
@@ -89,8 +89,7 @@ export class SidebarViewController {
*
* 根据存储库打开或关闭状态向 sidebarView 发送对应消息
*/
- private _checkIsSCMRepoOpened(): void {
- const gitExtension = vscode.extensions.getExtension("vscode.git");
+ private async _checkIsSCMRepoOpened(): Promise {
const openedMsg = {
type: "CodeOpenedRepoMsg",
content: "Git repo is opened",
@@ -99,60 +98,28 @@ export class SidebarViewController {
type: "CodeClosedRepoMsg",
content: "Git repo is closed",
};
-
- // 获取插件对象失败
- if (!gitExtension) {
- logger.error(`Failed to acquire git extension`);
- vscode.window.showErrorMessage(
- vscode.l10n.t(
- "Failed to communicate with Git extension. RVPortingTool requires Git extension to work properly.",
- ),
- );
+ const gitApi = await GitUtility.getGitAPI();
+ if (!gitApi) {
+ logger.info(`Git extension not available`);
this._view?.webview.postMessage(closedMsg);
return;
}
+ // 注册回调事件
+ gitApi.onDidOpenRepository((_) => {
+ logger.info(`onDidOpenRepository triggered`);
+ this._view?.webview.postMessage(openedMsg);
+ });
+ gitApi.onDidCloseRepository((_) => {
+ logger.info(`onDidCloseRepository triggered`);
+ this._view?.webview.postMessage(closedMsg);
+ });
- // 调用 exports 前必须检查 Git 插件是否激活,若未激活需先激活
- if (!gitExtension.isActive) {
- logger.info(`Activating git extension...`);
- gitExtension.activate().then(() => {
- logger.info(`Git extension activated`);
- this._checkIsSCMRepoOpened();
- });
- return;
- }
-
- // 检查 Git 插件初始化状态
- const gitApi: gitTypes.API = gitExtension.exports.getAPI(1);
- if (gitApi.state === "uninitialized") {
- // Git 插件尚未初始化,注册回调函数等待完成初始化
- gitApi.onDidChangeState((state) => {
- if (state === "initialized") {
- logger.info(`Git extension initialized`);
-
- // 注册回调事件
- gitApi.onDidOpenRepository((_) => {
- logger.info(`onDidOpenRepository triggered`);
- this._view?.webview.postMessage(openedMsg);
- });
- gitApi.onDidCloseRepository((_) => {
- logger.info(`onDidCloseRepository triggered`);
- this._view?.webview.postMessage(closedMsg);
- });
-
- // 主动检查一次
- this._checkIsSCMRepoOpened();
- }
- });
- return;
- }
-
- // 通过 Git API 检查存储库数量
- if (gitApi.repositories.length > 0) {
- logger.info(`${gitApi.repositories.length} git repositories available`);
+ // 主动检查一次
+ if (await GitUtility.checkIsSCMRepoOpened()) {
+ logger.info(`checkIsSCMRepoOpened returned true`);
this._view?.webview.postMessage(openedMsg);
} else {
- logger.info(`No git repository available`);
+ logger.info(`checkIsSCMRepoOpened returned false`);
this._view?.webview.postMessage(closedMsg);
}
}
diff --git a/client/src/utils/git.ts b/client/src/utils/git.ts
new file mode 100644
index 0000000..b55a5d9
--- /dev/null
+++ b/client/src/utils/git.ts
@@ -0,0 +1,92 @@
+/***************************************************************************************
+ * Copyright (c) 2023-2024 RVSmartPorting. All rights reserved.
+ * RVPortingTool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ **************************************************************************************/
+
+/***************************************************************************************
+ * Git Extension Utilities for RVPortingTool VSCode Extension
+ *
+ * Author: Lightning Rainstorm
+ * liccc
+ * Last Change: Sep 12, 2024
+ **************************************************************************************/
+
+import * as vscode from "vscode";
+import * as gitTypes from "../types/git";
+import { ClientLogger } from "../utils/log";
+
+const logger = ClientLogger.getLogger("GitUtility");
+
+export class GitUtility {
+ /**
+ * 获取 Git 插件 API
+ */
+ public static async getGitAPI(): Promise {
+ return new Promise(async (resolve) => {
+ const gitExtension = vscode.extensions.getExtension("vscode.git");
+
+ // 获取插件对象失败
+ if (!gitExtension) {
+ logger.error(`Failed to acquire git extension`);
+ vscode.window.showErrorMessage(
+ vscode.l10n.t(
+ "Failed to communicate with Git extension. RVPortingTool requires Git extension to work properly.",
+ ),
+ );
+ resolve(null);
+ return;
+ }
+
+ // 调用 exports 前必须检查 Git 插件是否激活,若未激活需先激活
+ if (!gitExtension.isActive) {
+ logger.info(`Activating git extension...`);
+ await gitExtension.activate();
+ }
+
+ // 检查 Git 插件初始化状态
+ const gitApi: gitTypes.API = gitExtension.exports.getAPI(1);
+ if (gitApi.state === "uninitialized") {
+ // Git 插件尚未初始化,注册回调函数等待完成初始化
+ gitApi.onDidChangeState((state) => {
+ if (state === "initialized") {
+ logger.info(`Git extension initialized`);
+ resolve(gitApi);
+ }
+ });
+ } else {
+ resolve(gitApi);
+ }
+ });
+ }
+ /**
+ * 检测当前是否已打开 Git 存储库
+ *
+ * 根据存储库打开或关闭状态向 sidebarView 发送对应消息
+ */
+ public static async checkIsSCMRepoOpened(): Promise {
+ return new Promise(async (resolve) => {
+ // 获取 Git API
+ const gitApi = await this.getGitAPI();
+ if (!gitApi) {
+ resolve(false);
+ return;
+ }
+
+ // 通过 Git API 检查存储库数量
+ if (gitApi.repositories.length > 0) {
+ logger.info(`${gitApi.repositories.length} git repositories available`);
+ resolve(true);
+ } else {
+ logger.info(`No git repository available`);
+ resolve(false);
+ }
+ });
+ }
+}
--
Gitee
From acf04b887be41e873f72e6469c6a9d584cdbde8f Mon Sep 17 00:00:00 2001
From: liccc
Date: Thu, 12 Sep 2024 13:05:47 +0800
Subject: [PATCH 14/17] =?UTF-8?q?feat:=20=E5=88=9D=E6=AD=A5=E5=AE=9E?=
=?UTF-8?q?=E7=8E=B0=20CodeScanManager=20=E6=BC=94=E7=A4=BA=E6=95=88?=
=?UTF-8?q?=E6=9E=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/codeScan/codeScanManager.ts | 225 +++++++++++
client/src/codeScan/demoData.ts | 49 +++
client/src/extension.ts | 4 +
.../src/sidebarView/sidebarViewController.ts | 3 +
client/src/sidebarView/sidebarViewProvider.ts | 2 +-
client/src/types/codeScan.ts | 42 ++
client/src/utils/git.ts | 28 ++
common/src/types/command.ts | 3 +
common/src/types/sidebarView.ts | 11 +
l10n/bundle.l10n.json | 15 +-
l10n/bundle.l10n.zh-cn.json | 13 +
package.json | 4 +
package.nls.json | 3 +-
package.nls.zh-cn.json | 3 +-
testRoot/example2.c | 23 ++
testRoot/example2.json | 366 ++++++++++++++++++
webview/src/sidebarView/index.ts | 7 +
17 files changed, 797 insertions(+), 4 deletions(-)
create mode 100644 client/src/codeScan/codeScanManager.ts
create mode 100644 client/src/codeScan/demoData.ts
create mode 100644 client/src/types/codeScan.ts
create mode 100644 testRoot/example2.c
create mode 100644 testRoot/example2.json
diff --git a/client/src/codeScan/codeScanManager.ts b/client/src/codeScan/codeScanManager.ts
new file mode 100644
index 0000000..d4b4b27
--- /dev/null
+++ b/client/src/codeScan/codeScanManager.ts
@@ -0,0 +1,225 @@
+/***************************************************************************************
+ * Copyright (c) 2023-2024 RVSmartPorting. All rights reserved.
+ * RVPortingTool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ **************************************************************************************/
+
+/***************************************************************************************
+ * Code Scan Manager for RVPortingTool VSCode Extension
+ *
+ * Author: Lightning Rainstorm
+ * liccc
+ * Last Change: Sep 11, 2024
+ **************************************************************************************/
+
+import * as fs from "fs";
+import * as vscode from "vscode";
+import * as lsp from "vscode-languageclient";
+import { CommandID } from "../../../common/src/types/command";
+import { LSPNotificationID } from "../../../common/src/types/notification";
+import { ReportMgrLoadParams } from "../../../common/src/types/reportManager";
+import { ScanServerConfig } from "../types/codeScan";
+import { GitUtility } from "../utils/git";
+import { ClientLogger } from "../utils/log";
+import { demoData } from "./demoData";
+
+const logger = ClientLogger.getLogger("CodeScanManager");
+
+export class CodeScanManager {
+ private static _instance: CodeScanManager;
+
+ private constructor(
+ private readonly _context: vscode.ExtensionContext,
+ private readonly _client: lsp.BaseLanguageClient,
+ ) {}
+
+ public static getInstance(): CodeScanManager {
+ if (!this._instance) {
+ const msg = "CodeScanManager has not been initialized yet";
+ logger.error(msg);
+ throw new Error(msg);
+ }
+ return this._instance;
+ }
+
+ public static init(context: vscode.ExtensionContext, client: lsp.BaseLanguageClient): void {
+ this._instance = new CodeScanManager(context, client);
+
+ context.subscriptions.push(
+ // 注册命令 代码扫描:开始扫描
+ vscode.commands.registerCommand(CommandID.codeScanStart, () => {
+ this._instance.startScan();
+ }),
+ );
+ }
+
+ public async startScan(): Promise {
+ logger.info("Start code scan");
+ const server = await this.chooseScanServer();
+
+ // 检查是否接受扫描服务器的许可协议
+ if (!server.acceptedLicense) {
+ const accepted = await this.showServerLicense(server);
+ if (!accepted) {
+ return;
+ }
+ }
+
+ // 检查是否已打开存储库
+ if (!(await GitUtility.checkIsSCMRepoOpened())) {
+ vscode.window.showErrorMessage(
+ vscode.l10n.t("Cannot perform code scan! Please open a repository first"),
+ );
+ return;
+ }
+
+ // TODO: 当打开的工作区数量多于一个时,让用户选择工作区
+ // TODO: 当打开的存储库数量多于一个时,让用户选择存储库
+ // TODO: 检查工作区 .vscode/archive.tar.gz 是否可写
+
+ // ======== FOR DEMO USE ONLY ========
+ const sleep = (time: number) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(true);
+ }, time);
+ });
+ };
+
+ vscode.window.withProgress(
+ {
+ location: vscode.ProgressLocation.Notification,
+ title: vscode.l10n.t("Scanning code"),
+ cancellable: true,
+ },
+ async (progress, token) => {
+ return new Promise(async (resolve) => {
+ token.onCancellationRequested(() => {
+ logger.info("Scan cancelled by user");
+ });
+
+ progress.report({
+ message: vscode.l10n.t("Preparing archive..."),
+ increment: 0,
+ });
+
+ const workspace = vscode.workspace.workspaceFolders![0];
+ const archivePath = vscode.Uri.joinPath(workspace.uri, ".vscode/archive.tar.gz");
+ try {
+ await GitUtility.createGitArchive(workspace.uri.fsPath, archivePath.fsPath);
+ } catch (error) {
+ logger.error(error);
+ resolve();
+ }
+
+ await sleep(2000);
+
+ progress.report({
+ message: vscode.l10n.t("Uploading archive..."),
+ increment: 20,
+ });
+
+ await sleep(1500);
+
+ fs.unlinkSync(archivePath.fsPath);
+
+ progress.report({
+ message: vscode.l10n.t("Server analyzing code..."),
+ increment: 20,
+ });
+
+ await sleep(3000);
+
+ progress.report({
+ message: vscode.l10n.t("Server finalizing report..."),
+ increment: 20,
+ });
+
+ await sleep(1000);
+
+ progress.report({
+ message: vscode.l10n.t("Downloading report..."),
+ increment: 20,
+ });
+
+ await sleep(1500);
+
+ progress.report({
+ message: vscode.l10n.t("Loading report..."),
+ increment: 20,
+ });
+
+ await sleep(500);
+
+ // 通知 Language Server 读取报告
+ const reportUri = vscode.Uri.joinPath(workspace.uri, "example2.json");
+ this._client.sendNotification(LSPNotificationID.reportMgrSrvLoad, {
+ workspaceUri: workspace.uri.toString(),
+ reportUri: reportUri.toString(),
+ reloadConfirm: false,
+ });
+
+ await sleep(500);
+
+ resolve();
+ });
+ },
+ );
+
+ // ./====== FOR DEMO USE ONLY ========
+ }
+
+ /**
+ * 选择扫描服务器
+ *
+ * @returns 扫描服务器配置
+ */
+ public async chooseScanServer(): Promise {
+ return new Promise((resolve) => {
+ const quickPick = vscode.window.createQuickPick();
+ quickPick.items = demoData.scanServers.map(
+ (server) =>
+ {
+ label: server.name,
+ description: server.endpoint,
+ },
+ );
+ quickPick.onDidAccept(() => {
+ const selected = quickPick.selectedItems[0];
+ if (selected) {
+ resolve(demoData.scanServers.find((server) => server.name === selected.label)!);
+ }
+ quickPick.dispose();
+ });
+ quickPick.show();
+ });
+ }
+
+ public async showServerLicense(server: ScanServerConfig): Promise {
+ return new Promise((resolve) => {
+ const licText = demoData.serverLicense;
+ vscode.window
+ .showInformationMessage(
+ licText,
+ {
+ modal: true,
+ },
+ vscode.l10n.t("Accept License"),
+ )
+ .then((value) => {
+ if (value === vscode.l10n.t("Accept License")) {
+ server.acceptedLicense = true;
+ resolve(true);
+ } else {
+ resolve(false);
+ }
+ });
+ });
+ }
+}
diff --git a/client/src/codeScan/demoData.ts b/client/src/codeScan/demoData.ts
new file mode 100644
index 0000000..988e434
--- /dev/null
+++ b/client/src/codeScan/demoData.ts
@@ -0,0 +1,49 @@
+/***************************************************************************************
+ * Copyright (c) 2023-2024 RVSmartPorting. All rights reserved.
+ * RVPortingTool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ **************************************************************************************/
+
+/***************************************************************************************
+ * Demo Data of Code Scan Manager for RVPortingTool VSCode Extension
+ *
+ * Author: Lightning Rainstorm
+ * liccc
+ * Last Change: Sep 11, 2024
+ **************************************************************************************/
+
+import * as vscode from "vscode";
+import { ScanServerConfig } from "../types/codeScan";
+
+export const demoData = {
+ scanServers: [
+ {
+ name: vscode.l10n.t("RVPortingTool Official Server"),
+ endpoint: "https://code-scan.rvpt.top/server-1",
+ userName: "demo",
+ secretKey: "RVPortingTool",
+ keepCode: true,
+ },
+ {
+ name: vscode.l10n.t("Self-deployed Server A"),
+ endpoint: "https://self-deployed.scan.server",
+ userName: "demo",
+ secretKey: "RVPortingTool",
+ keepCode: true,
+ },
+ ],
+
+ serverLicense: vscode.l10n.t(
+ "RVPortingTool Official Code Scanning Server License\n\n\
+1. This is a demo server, please do not use it for production.\n\
+2. Your code might be store on this server for a while, please do not store any sensitive information.\n\
+3. This server is provided as-is, without any warranty or liability.\n\
+4. If you have any questions or concerns, please contact us at support@rvpt.top.",
+ ),
+};
diff --git a/client/src/extension.ts b/client/src/extension.ts
index 53b90a5..5a48682 100644
--- a/client/src/extension.ts
+++ b/client/src/extension.ts
@@ -25,6 +25,7 @@ import {
ServerOptions,
TransportKind,
} from "vscode-languageclient/node";
+import { CodeScanManager } from "./codeScan/codeScanManager";
import { ReportManagerClient } from "./reportManagerClient";
import { SidebarHelper } from "./sidebarHelper";
import { ClientLogger } from "./utils/log";
@@ -90,6 +91,9 @@ export async function activate(context: vscode.ExtensionContext) {
// 初始化 Sidebar Helper
SidebarHelper.init(context);
+ // 初始化 Code Scan Manager
+ CodeScanManager.init(context, client);
+
// 启动 Language Client,同时启动 Server
// client.start();
}
diff --git a/client/src/sidebarView/sidebarViewController.ts b/client/src/sidebarView/sidebarViewController.ts
index 6440935..0f80434 100644
--- a/client/src/sidebarView/sidebarViewController.ts
+++ b/client/src/sidebarView/sidebarViewController.ts
@@ -143,6 +143,9 @@ export class SidebarViewController {
} else if (viewTypes.SidebarViewMsgUtil.isUserClearReportMsg(message)) {
// WebView 请求清除报告
vscode.commands.executeCommand(CommandID.reportMgrClearAllReport);
+ } else if (viewTypes.SidebarViewMsgUtil.isUserStartScanMsg(message)) {
+ // WebView 请求开始扫描
+ vscode.commands.executeCommand(CommandID.codeScanStart);
}
}
}
diff --git a/client/src/sidebarView/sidebarViewProvider.ts b/client/src/sidebarView/sidebarViewProvider.ts
index 5082f3e..62fed1d 100644
--- a/client/src/sidebarView/sidebarViewProvider.ts
+++ b/client/src/sidebarView/sidebarViewProvider.ts
@@ -109,7 +109,7 @@ export class SidebarViewProvider implements vscode.WebviewViewProvider {
${vscode.l10n.t("Detected repository, you can scan code now")}
-
${vscode.l10n.t("Upload and Scan Source Code")}
+
${vscode.l10n.t("Upload and Scan Source Code")}
${vscode.l10n.t("Import Code Check Report")}
diff --git a/client/src/types/codeScan.ts b/client/src/types/codeScan.ts
new file mode 100644
index 0000000..138cf82
--- /dev/null
+++ b/client/src/types/codeScan.ts
@@ -0,0 +1,42 @@
+/***************************************************************************************
+ * Copyright (c) 2023-2024 RVSmartPorting. All rights reserved.
+ * RVPortingTool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ **************************************************************************************/
+
+/***************************************************************************************
+ * Code Scan Data Definition for RVPortingTool VSCode Extension
+ *
+ * Author: Lightning Rainstorm
+ * liccc
+ * Last Change: Sep 11, 2024
+ **************************************************************************************/
+
+/**
+ * 代码扫描服务器配置
+ */
+export interface ScanServerConfig {
+ /** 代码扫描服务器名称 */
+ name: string;
+
+ /** 代码扫描服务器 API 地址 */
+ endpoint: string;
+
+ /** 代码扫描服务器 用户名 */
+ userName: string;
+
+ /** 代码扫描服务器 Secret */
+ secretKey: string;
+
+ /** 代码扫描服务器 隐私设置:是否已同意协议 */
+ acceptedLicense?: boolean;
+
+ /** 代码扫描服务器 隐私设置:是否保留代码 */
+ keepCode?: boolean;
+}
diff --git a/client/src/utils/git.ts b/client/src/utils/git.ts
index b55a5d9..c2cb992 100644
--- a/client/src/utils/git.ts
+++ b/client/src/utils/git.ts
@@ -18,6 +18,7 @@
* Last Change: Sep 12, 2024
**************************************************************************************/
+import * as child_process from "child_process";
import * as vscode from "vscode";
import * as gitTypes from "../types/git";
import { ClientLogger } from "../utils/log";
@@ -89,4 +90,31 @@ export class GitUtility {
}
});
}
+
+ public static async createGitArchive(repoFsPath: string, archiveFsPath: string): Promise {
+ return new Promise(async (resolve, reject) => {
+ const gitApi = await GitUtility.getGitAPI();
+ const gitExecPath = gitApi?.git.path;
+ const gitExecParams = ["archive", "-o", '"' + archiveFsPath + '"', "--format=tar.gz", "HEAD"];
+
+ // Use Node.js child_process to execute git archive command
+ child_process.exec(
+ `"${gitExecPath}" ${gitExecParams.join(" ")}`,
+ {
+ cwd: repoFsPath,
+ encoding: "utf-8",
+ },
+ (err, stdout, stderr) => {
+ if (err) {
+ vscode.window.showErrorMessage(
+ vscode.l10n.t("Failed to create git archive: {0}", err.message),
+ );
+ reject(err);
+ }
+ logger.info("Archive created successfully");
+ resolve();
+ },
+ );
+ });
+ }
}
diff --git a/common/src/types/command.ts b/common/src/types/command.ts
index df55f33..681114f 100644
--- a/common/src/types/command.ts
+++ b/common/src/types/command.ts
@@ -42,4 +42,7 @@ export class CommandID {
/** 侧边栏:刷新状态 */
public static sidebarViewRefreshState = "rvCodingAsst.sidebarHelper.refreshState";
+
+ /** 代码扫描:开始扫描 */
+ public static codeScanStart = "rvCodingAsst.codeScan.start";
}
diff --git a/common/src/types/sidebarView.ts b/common/src/types/sidebarView.ts
index 8e77ce3..c56585e 100644
--- a/common/src/types/sidebarView.ts
+++ b/common/src/types/sidebarView.ts
@@ -87,6 +87,12 @@ export interface CodeNoReportMsg {
type: "CodeNoReportMsg";
}
+/** SidebarView 用户开始扫描消息 */
+export interface UserStartScanMsg {
+ /** type */
+ type: "UserStartScanMsg";
+}
+
/** SidebarView 消息类型检查辅助类 */
export class SidebarViewMsgUtil {
/** 判断是否为 SidebarView 加载完毕消息 */
@@ -138,4 +144,9 @@ export class SidebarViewMsgUtil {
public static isCodeNoReportMsg(msg: any): msg is CodeNoReportMsg {
return msg.type === "CodeNoReportMsg";
}
+
+ /** 判断是否为 SidebarView 用户开始扫描消息 */
+ public static isUserStartScanMsg(msg: any): msg is UserStartScanMsg {
+ return msg.type === "UserStartScanMsg";
+ }
}
diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json
index 4cfd7da..f515695 100644
--- a/l10n/bundle.l10n.json
+++ b/l10n/bundle.l10n.json
@@ -1,6 +1,7 @@
{
"ARM": "ARM",
"ARM architecture-related macro": "ARM architecture-related macro",
+ "Accept License": "Accept License",
"Architecture judgement macro statement block": "Architecture judgement macro statement block",
"Architecture-related built-in function": "Architecture-related built-in function",
"Architecture-related built-in macro statement block": "Architecture-related built-in macro statement block",
@@ -9,12 +10,15 @@
"Are you sure to clear all loaded reports? This operation will remove it from workspace cache too!": "Are you sure to clear all loaded reports? This operation will remove it from workspace cache too!",
"Are you sure to temporarily unload all loaded reports? The reports will be automatically load next time after reloading or restarting Workspace/VSCode.": "Are you sure to temporarily unload all loaded reports? The reports will be automatically load next time after reloading or restarting Workspace/VSCode.",
"C/C++": "C/C++",
+ "Cannot perform code scan! Please open a repository first": "Cannot perform code scan! Please open a repository first",
"Clear Code Check Report": "Clear Code Check Report",
"Code Scan Report": "Code Scan Report",
"Confirm": "Confirm",
"Detected repository, you can scan code now": "Detected repository, you can scan code now",
+ "Downloading report...": "Downloading report...",
"Export Code Check Report": "Export Code Check Report",
"Failed to communicate with Git extension. RVPortingTool requires Git extension to work properly.": "Failed to communicate with Git extension. RVPortingTool requires Git extension to work properly.",
+ "Failed to create git archive: {0}": "Failed to create git archive: {0}",
"Failed to load report": "Failed to load report",
"Failed to load report: {0}: {1}": "Failed to load report: {0}: {1}",
"Failed to load rule details of {0}{1}": "Failed to load rule details of {0}{1}",
@@ -30,12 +34,16 @@
"Import Code Check Report": "Import Code Check Report",
"Inline architecture-related shell script": "Inline architecture-related shell script",
"Inline assembly": "Inline assembly",
+ "Loading report...": "Loading report...",
"Network error": "Network error",
"No Wiki pages have been opened yet.": "No Wiki pages have been opened yet.",
"Please choose a workspace for displaying report": "Please choose a workspace for displaying report",
"Please choose code scanning report file": "Please choose code scanning report file",
"Please open a folder as workspace before loading report": "Please open a folder as workspace before loading report",
"Please {0} to scan code": "Please {0} to scan code",
+ "Preparing archive...": "Preparing archive...",
+ "RVPortingTool Official Code Scanning Server License\n\n\r\n1. This is a demo server, please do not use it for production.\n\r\n2. Your code might be store on this server for a while, please do not store any sensitive information.\n\r\n3. This server is provided as-is, without any warranty or liability.\n\r\n4. If you have any questions or concerns, please contact us at support@rvpt.top.": "RVPortingTool Official Code Scanning Server License\n\n\r\n1. This is a demo server, please do not use it for production.\n\r\n2. Your code might be store on this server for a while, please do not store any sensitive information.\n\r\n3. This server is provided as-is, without any warranty or liability.\n\r\n4. If you have any questions or concerns, please contact us at support@rvpt.top.",
+ "RVPortingTool Official Server": "RVPortingTool Official Server",
"Report clear confirm": "Report clear confirm",
"Report reloading confirm": "Report reloading confirm",
"Report unload confirm": "Report unload confirm",
@@ -44,6 +52,10 @@
"Save": "Save",
"Save Code Scan Report As...": "Save Code Scan Report As...",
"Save as...": "Save as...",
+ "Scanning code": "Scanning code",
+ "Self-deployed Server A": "Self-deployed Server A",
+ "Server analyzing code...": "Server analyzing code...",
+ "Server finalizing report...": "Server finalizing report...",
"Suspected ARM architecture-related macro": "Suspected ARM architecture-related macro",
"Suspected architecture-related enum type": "Suspected architecture-related enum type",
"Suspected architecture-related macro": "Suspected architecture-related macro",
@@ -52,6 +64,7 @@
"Unknown reason": "Unknown reason",
"Unload Code Check Report": "Unload Code Check Report",
"Upload and Scan Source Code": "Upload and Scan Source Code",
+ "Uploading archive...": "Uploading archive...",
"Welcome to RVPortingTool: Make RISC-V Porting Easier!": "Welcome to RVPortingTool: Make RISC-V Porting Easier!",
"X86": "X86",
"X86 architecture-specified macro": "X86 architecture-specified macro",
@@ -76,4 +89,4 @@
"shifting": "shifting",
"signed integer": "signed integer",
"system call": "system call"
-}
+}
\ No newline at end of file
diff --git a/l10n/bundle.l10n.zh-cn.json b/l10n/bundle.l10n.zh-cn.json
index 92c78c7..540a869 100644
--- a/l10n/bundle.l10n.zh-cn.json
+++ b/l10n/bundle.l10n.zh-cn.json
@@ -1,6 +1,7 @@
{
"ARM": "ARM",
"ARM architecture-related macro": "ARM 架构特有宏",
+ "Accept License": "接受许可协议",
"Architecture judgement macro statement block": "架构判断宏语句块",
"Architecture-related built-in function": "架构相关 builtin 函数",
"Architecture-related built-in macro statement block": "架构相关内置宏语句块",
@@ -9,12 +10,15 @@
"Are you sure to clear all loaded reports? This operation will remove it from workspace cache too!": "您确定要清除所有已加载的报告吗?此操作会同时将报告从工作区缓存中删除!",
"Are you sure to temporarily unload all loaded reports? The reports will be automatically load next time after reloading or restarting Workspace/VSCode.": "您确定要临时卸载所有已加载的报告吗?下次重新加载或重启 工作区/VSCode 时,报告将自动加载。",
"C/C++": "C/C++",
+ "Cannot perform code scan! Please open a repository first": "无法执行代码检查!请先打开一个存储库",
"Clear Code Check Report": "清除代码扫描报告",
"Code Scan Report": "代码扫描报告",
"Confirm": "确认",
"Detected repository, you can scan code now": "已检测到存储库,可使用代码扫描功能",
+ "Downloading report...": "正在下载报告...",
"Export Code Check Report": "导出代码扫描报告",
"Failed to communicate with Git extension. RVPortingTool requires Git extension to work properly.": "无法与 Git 扩展通信。睿迁工具需要使用 Git 扩展才能正常工作。",
+ "Failed to create git archive: {0}": "创建源代码归档包失败: {0}",
"Failed to load report": "加载报告失败",
"Failed to load report: {0}: {1}": "加载报告失败: {0}: {1}",
"Failed to load rule details of {0}{1}": "加载检查规则【{0}{1}】详细信息失败",
@@ -30,12 +34,16 @@
"Import Code Check Report": "导入代码扫描报告",
"Inline architecture-related shell script": "内嵌架构相关 Shell 脚本",
"Inline assembly": "内联汇编",
+ "Loading report...": "正在加载报告...",
"Network error": "网络错误",
"No Wiki pages have been opened yet.": "目前未打开任何 Wiki 页面。",
"Please choose a workspace for displaying report": "请选择报告对应的工作区",
"Please choose code scanning report file": "请选择代码扫描报告文件",
"Please open a folder as workspace before loading report": "加载报告前请先打开一个工作区",
"Please {0} to scan code": "请 {0} 以使用代码扫描功能",
+ "Preparing archive...": "正在创建源代码归档包...",
+ "RVPortingTool Official Code Scanning Server License\n\n\r\n1. This is a demo server, please do not use it for production.\n\r\n2. Your code might be store on this server for a while, please do not store any sensitive information.\n\r\n3. This server is provided as-is, without any warranty or liability.\n\r\n4. If you have any questions or concerns, please contact us at support@rvpt.top.": "RVPortingTool Official Code Scanning Server License\n\n\r\n1. This is a demo server, please do not use it for production.\n\r\n2. Your code might be store on this server for a while, please do not store any sensitive information.\n\r\n3. This server is provided as-is, without any warranty or liability.\n\r\n4. If you have any questions or concerns, please contact us at support@rvpt.top.",
+ "RVPortingTool Official Server": "睿迁官方服务器",
"Report clear confirm": "请确认是否清除所有报告",
"Report reloading confirm": "请确认是否重新加载报告数据",
"Report unload confirm": "请确认是否卸载所有报告",
@@ -44,6 +52,10 @@
"Save": "保存",
"Save Code Scan Report As...": "将代码扫描报告另存为...",
"Save as...": "将报告另存为...",
+ "Scanning code": "扫描代码",
+ "Self-deployed Server A": "私有化部署服务器测试",
+ "Server analyzing code...": "服务端正在分析代码...",
+ "Server finalizing report...": "服务端正在生成报告...",
"Suspected ARM architecture-related macro": "疑似 ARM 架构特有宏",
"Suspected architecture-related enum type": "疑似架构相关枚举类型",
"Suspected architecture-related macro": "疑似架构相关宏",
@@ -52,6 +64,7 @@
"Unknown reason": "未知原因",
"Unload Code Check Report": "卸载代码扫描报告",
"Upload and Scan Source Code": "上传并扫描源码",
+ "Uploading archive...": "正在上传源代码归档包...",
"Welcome to RVPortingTool: Make RISC-V Porting Easier!": "欢迎使用睿迁工具:让 RISC-V 移植更简单!",
"X86": "X86",
"X86 architecture-specified macro": "X86 架构特有宏",
diff --git a/package.json b/package.json
index 3dd1a6f..229ad5e 100644
--- a/package.json
+++ b/package.json
@@ -88,6 +88,10 @@
{
"command": "rvCodingAsst.sidebarHelper.refreshState",
"title": "%rvCodingAsst.command.sidebarHelper.refreshState%"
+ },
+ {
+ "command": "rvCodingAsst.codeScan.start",
+ "title": "%rvCodingAsst.command.codeScan.start%"
}
],
"viewsContainers": {
diff --git a/package.nls.json b/package.nls.json
index 6528e30..55dc447 100644
--- a/package.nls.json
+++ b/package.nls.json
@@ -14,5 +14,6 @@
"rvCodingAsst.viewContainers.activitybar.title": "RVPortingTool",
"rvCodingAsst.view.wiki.name": "RV Porting Wiki",
"rvCodingAsst.view.wiki.contextualTitle": "RVPortingTool",
- "rvCodingAsst.view.sidebar.name": "RVPortingTool"
+ "rvCodingAsst.view.sidebar.name": "RVPortingTool",
+ "rvCodingAsst.command.codeScan.start": "RVPortingTool: Start Code Scan"
}
diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json
index f242591..14070ef 100644
--- a/package.nls.zh-cn.json
+++ b/package.nls.zh-cn.json
@@ -14,5 +14,6 @@
"rvCodingAsst.viewContainers.activitybar.title": "RVPortingTool",
"rvCodingAsst.view.wiki.name": "迁移知识库",
"rvCodingAsst.view.wiki.contextualTitle": "RVPortingTool",
- "rvCodingAsst.view.sidebar.name": "睿迁助手"
+ "rvCodingAsst.view.sidebar.name": "睿迁助手",
+ "rvCodingAsst.command.codeScan.start": "RVPortingTool: 开始扫描"
}
diff --git a/testRoot/example2.c b/testRoot/example2.c
new file mode 100644
index 0000000..ede4e40
--- /dev/null
+++ b/testRoot/example2.c
@@ -0,0 +1,23 @@
+/* This program assumes that a whole number of return instructions fit into
+ * 32 bits, and that 32-bit alignment is sufficient for a branch destination.
+ * For architectures where this is not true, fiddling with RETURN_INSTR_TYPE
+ * can be enough.
+ */
+
+#if defined __i386__ || defined __x86_64__ || defined __i386 || \
+ defined __x86_64 || defined _M_IX86 || defined _M_AMD64
+# define RETURN_INSTR 0xC3C3C3C3 /* ret; ret; ret; ret */
+
+#elif defined __arm__ || defined _M_ARM
+# define RETURN_INSTR 0xE12FFF1E /* bx lr */
+
+#endif
+
+// Macro `TEST_MACRO` is architecture-irrelevant
+#ifndef TEST_MACRO
+asm ("mov eax, 1");
+__asm ( "mov ebx, 0ffh" );
+__asm__ volatile ("mov eax, 5\n"
+ "add eax, 6\n"
+ "mov result, eax");
+#endif
diff --git a/testRoot/example2.json b/testRoot/example2.json
new file mode 100644
index 0000000..891419d
--- /dev/null
+++ b/testRoot/example2.json
@@ -0,0 +1,366 @@
+{
+ "version": 1,
+ "timestamp": 1725170530000,
+ "problems": [
+ {
+ "id": "000001",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 12,
+ "lineUpto": 7,
+ "colUpto": 20,
+ "comment": "__i386__"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000002",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 32,
+ "lineUpto": 7,
+ "colUpto": 42,
+ "comment": "__x86_64__"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000003",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 54,
+ "lineUpto": 7,
+ "colUpto": 60,
+ "comment": "__i386"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000004",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 12,
+ "lineUpto": 8,
+ "colUpto": 20,
+ "comment": "__x86_64"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000005",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 32,
+ "lineUpto": 8,
+ "colUpto": 39,
+ "comment": "_M_IX86"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000006",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 51,
+ "lineUpto": 8,
+ "colUpto": 59,
+ "comment": "_M_IX86"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000007",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 9,
+ "colFrom": 10,
+ "lineUpto": 9,
+ "colUpto": 22,
+ "comment": "RETURN_INSTR"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 12,
+ "lineUpto": 7,
+ "colUpto": 20,
+ "comment": "在 X86 架构特有宏下定义: __i386__"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 32,
+ "lineUpto": 7,
+ "colUpto": 42,
+ "comment": "在 X86 架构特有宏下定义: __x86_64__"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 54,
+ "lineUpto": 7,
+ "colUpto": 60,
+ "comment": "在 X86 架构特有宏下定义: __i386"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 12,
+ "lineUpto": 8,
+ "colUpto": 20,
+ "comment": "在 X86 架构特有宏下定义: __x86_64"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 32,
+ "lineUpto": 8,
+ "colUpto": 39,
+ "comment": "在 X86 架构特有宏下定义: _M_IX86"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 51,
+ "lineUpto": 8,
+ "colUpto": 59,
+ "comment": "在 X86 架构特有宏下定义: _M_IX86"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000008",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0001",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 11,
+ "colFrom": 14,
+ "lineUpto": 11,
+ "colUpto": 21,
+ "comment": "__arm__"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000009",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0001",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 11,
+ "colFrom": 33,
+ "lineUpto": 11,
+ "colUpto": 39,
+ "comment": "_M_ARM"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000010",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0002",
+ "level": 3,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 12,
+ "colFrom": 10,
+ "lineUpto": 12,
+ "colUpto": 22,
+ "comment": "_M_ARM"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 11,
+ "colFrom": 14,
+ "lineUpto": 11,
+ "colUpto": 21,
+ "comment": "在 ARM 架构特有宏下定义: __arm__"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 11,
+ "colFrom": 33,
+ "lineUpto": 11,
+ "colUpto": 39,
+ "comment": "在 ARM 架构特有宏下定义: _M_ARM"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000011",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0008",
+ "level": 2,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "缺少针对 RISC-V 架构的分支条件",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 14,
+ "colFrom": 0,
+ "lineUpto": 14,
+ "colUpto": 6,
+ "comment": "缺少针对 RISC-V 架构的分支条件"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000012",
+ "state": 1,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0005",
+ "level": 1,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "未受架构特有宏保护的内联汇编代码",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 18,
+ "colFrom": 0,
+ "lineUpto": 22,
+ "colUpto": 37,
+ "comment": "未受架构特有宏保护的内联汇编代码"
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/webview/src/sidebarView/index.ts b/webview/src/sidebarView/index.ts
index 4b1b44b..e6e2c7b 100644
--- a/webview/src/sidebarView/index.ts
+++ b/webview/src/sidebarView/index.ts
@@ -60,6 +60,13 @@ import * as viewTypes from "../../../common/src/types/sidebarView";
type: "UserClearReportMsg",
});
});
+
+ // cmd-start-scan: 开始代码扫描
+ onClickMap.set("cmd-start-scan", () => {
+ vscode.postMessage({
+ type: "UserStartScanMsg",
+ });
+ });
};
const showUIElements = (clsNames: string[]) => {
--
Gitee
From d7bc9565fe20915ef5b82c0565eccb6a9577f4fd Mon Sep 17 00:00:00 2001
From: liccc
Date: Thu, 12 Sep 2024 13:06:22 +0800
Subject: [PATCH 15/17] =?UTF-8?q?enhance:=20=E4=BC=98=E5=8C=96=E8=AF=8A?=
=?UTF-8?q?=E6=96=AD=E9=97=AE=E9=A2=98=E6=98=BE=E7=A4=BA=E6=95=88=E6=9E=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/src/reportToDiagnostic.ts | 7 ++++++-
testRoot/.vscode/settings.json | 3 ++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/server/src/reportToDiagnostic.ts b/server/src/reportToDiagnostic.ts
index e7b5571..0ff0d71 100644
--- a/server/src/reportToDiagnostic.ts
+++ b/server/src/reportToDiagnostic.ts
@@ -114,9 +114,14 @@ export async function refreshDocumentDiagnostics(
),
);
} else if (i === 1) {
+ let desc = ruleInfo ? ruleInfo.desc : "";
+ if (desc.length > 0 && pbData.desc && pbData.desc.length > 0) {
+ desc += ": ";
+ }
+ desc += pbData.desc;
mainDiag = lsp.Diagnostic.create(
lspRange,
- ruleInfo ? ruleInfo.desc : pbData.desc,
+ desc,
srcRange.level ? srcRange.level : problem.level,
({
target: "vscode://tcse-iscas.rvportingtool/".concat(
diff --git a/testRoot/.vscode/settings.json b/testRoot/.vscode/settings.json
index a8c9f23..4fbd1b8 100644
--- a/testRoot/.vscode/settings.json
+++ b/testRoot/.vscode/settings.json
@@ -1,4 +1,5 @@
{
"rvportingtool.logLevel": "verbose",
- "rvportingtool.trace.server": "verbose"
+ "rvportingtool.trace.server": "verbose",
+ "C_Cpp.errorSquiggles": "disabled"
}
--
Gitee
From f0a9390487cb1fcd6ef90e1509dfd5194e6de5bc Mon Sep 17 00:00:00 2001
From: liccc
Date: Thu, 12 Sep 2024 14:07:06 +0800
Subject: [PATCH 16/17] chore: update tsc build config
---
.vscode/launch.json | 18 ++++++++++++++++++
.vscode/tasks.json | 13 +++++++++++++
client/tsconfig.json | 2 +-
common/tsconfig.json | 5 ++---
server/tsconfig.json | 4 ++--
webview/tsconfig.json | 2 +-
6 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 8745b17..4212f36 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -30,6 +30,24 @@
"preLaunchTask": "watch_esbuild"
// "postDebugTask": "terminateTasks"
},
+ {
+ "name": "Run Extension (TSC)",
+ "type": "extensionHost",
+ "request": "launch",
+ "runtimeExecutable": "${execPath}",
+ "args": [
+ "--extensionDevelopmentPath=${workspaceFolder}",
+ // Disable other extensions when debugging
+ "--disable-extensions",
+ // Specific workspace root directory
+ "${workspaceRoot}/testRoot"
+ ],
+ "outFiles": ["${workspaceFolder}/out/**/*.js"],
+ // Automatically attach language server child process
+ "autoAttachChildProcesses": true,
+ "preLaunchTask": "watch_tsc"
+ // "postDebugTask": "terminateTasks"
+ },
{
"name": "Extension Tests",
"type": "extensionHost",
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index f51869f..bcd7588 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -17,6 +17,19 @@
"isDefault": true
}
},
+ {
+ "type": "npm",
+ "script": "watch_tsc",
+ "label": "watch_tsc",
+ "problemMatcher": "$tsc-watch",
+ "isBackground": true,
+ "presentation": {
+ "reveal": "always"
+ },
+ "group": {
+ "kind": "build"
+ }
+ },
{
"type": "shell",
"label": "terminateTasks",
diff --git a/client/tsconfig.json b/client/tsconfig.json
index 92bb767..a6ed619 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -4,7 +4,7 @@
"module": "commonjs",
"target": "es2020",
"lib": ["es2020"],
- "outDir": "out",
+ "outDir": "../out",
"rootDir": "..",
"sourceMap": true,
"strict": true,
diff --git a/common/tsconfig.json b/common/tsconfig.json
index b0a84f9..5cfcf71 100644
--- a/common/tsconfig.json
+++ b/common/tsconfig.json
@@ -1,10 +1,9 @@
{
"compilerOptions": {
- "composite": true,
- "module": "commonjs",
+ "module": "Node16",
"target": "es2020",
"lib": ["es2020"],
- "outDir": "out",
+ "outDir": "../out",
"rootDir": "..",
"sourceMap": true,
"strict": true,
diff --git a/server/tsconfig.json b/server/tsconfig.json
index 92bb767..ed98fdc 100644
--- a/server/tsconfig.json
+++ b/server/tsconfig.json
@@ -4,13 +4,13 @@
"module": "commonjs",
"target": "es2020",
"lib": ["es2020"],
- "outDir": "out",
+ "outDir": "../out",
"rootDir": "..",
"sourceMap": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
- "include": ["src", "../common/src"],
+ "include": ["./src", "../common/src"],
"exclude": ["node_modules", ".vscode-test"]
}
diff --git a/webview/tsconfig.json b/webview/tsconfig.json
index c2857bd..d6bd23d 100644
--- a/webview/tsconfig.json
+++ b/webview/tsconfig.json
@@ -3,7 +3,7 @@
"composite": true,
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
- "outDir": "out",
+ "outDir": "../out",
"rootDir": "..",
"sourceMap": true,
"strict": true,
--
Gitee
From 6a8987a3d3700884a6750d72aa79b217eab92756 Mon Sep 17 00:00:00 2001
From: liccc
Date: Mon, 30 Sep 2024 23:35:42 +0800
Subject: [PATCH 17/17] =?UTF-8?q?feat:=20=E5=9F=BA=E4=BA=8E=E7=89=88?=
=?UTF-8?q?=E6=9C=AC=E6=8E=A7=E5=88=B6=E7=9A=84=E4=BB=A3=E7=A0=81=E4=B8=8A?=
=?UTF-8?q?=E4=BC=A0=E3=80=81=E9=97=AE=E9=A2=98=E8=B7=9F=E8=B8=AA=E5=AE=9E?=
=?UTF-8?q?=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/codeScan/codeCommit.ts | 65 +++++
client/src/codeScan/codeScanManager.ts | 21 +-
common/src/types/report.ts | 28 +-
server/src/compareWithCommit.ts | 166 +++++++++++
server/src/reportManager.ts | 78 +++++-
server/src/reportManagerServer.ts | 82 +++++-
server/src/reportToDiagnostic.ts | 95 ++++++-
server/src/server.ts | 1 +
testRoot/.gitignore | 1 +
testRoot/example-hint.json | 366 +++++++++++++++++++++++++
testRoot/example2.c | 3 +-
testRoot/example2.json | 39 ++-
12 files changed, 899 insertions(+), 46 deletions(-)
create mode 100644 client/src/codeScan/codeCommit.ts
create mode 100644 server/src/compareWithCommit.ts
create mode 100644 testRoot/.gitignore
create mode 100644 testRoot/example-hint.json
diff --git a/client/src/codeScan/codeCommit.ts b/client/src/codeScan/codeCommit.ts
new file mode 100644
index 0000000..7ac7316
--- /dev/null
+++ b/client/src/codeScan/codeCommit.ts
@@ -0,0 +1,65 @@
+import { exec } from "child_process";
+import * as vscode from "vscode";
+
+function runGitCommand(command: string, workspaceRoot: string): Promise {
+ return new Promise((resolve, reject) => {
+ exec(command, { cwd: workspaceRoot }, (error, stdout, stderr) => {
+ if (error) {
+ console.log(`stdout: ${stdout}; stderr: ${stderr}; error.message: ${error.message}`);
+ } else {
+ console.log(`stdout: ${stdout}; stderr: ${stderr}`);
+ }
+ resolve(stdout.trim());
+ });
+ });
+}
+
+export async function commitToCodeScanBranch(): Promise {
+ const workspaceRoot = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
+ console.log(workspaceRoot);
+ const targetBranch = "codeScan";
+
+ if (!workspaceRoot) {
+ vscode.window.showErrorMessage("无法找到工作区目录");
+ return undefined;
+ }
+
+ try {
+ // 获取当前分支
+ const currentBranch = await runGitCommand("git rev-parse --abbrev-ref HEAD", workspaceRoot);
+ vscode.window.showInformationMessage(`当前分支:${currentBranch}`);
+
+ // 暂存当前工作区的修改
+ // await runGitCommand("git stash", workspaceRoot);
+ await runGitCommand(`git stash`, workspaceRoot);
+
+ await runGitCommand(`git branch ${targetBranch}`, workspaceRoot);
+ await runGitCommand(`git checkout ${targetBranch}`, workspaceRoot);
+
+ // git checkout source-branch -- .
+ await runGitCommand(`git checkout ${currentBranch} -- .`, workspaceRoot);
+
+ await runGitCommand(`git stash apply`, workspaceRoot);
+
+ await runGitCommand(`git add -A`, workspaceRoot);
+
+ // 提交修改到目标分支
+ await runGitCommand(`git commit -m "commit for scan"`, workspaceRoot);
+
+ // 获取最新提交的哈希值
+ const commitHash = await runGitCommand("git log -1 --format=%H", workspaceRoot);
+
+ // 切换回原分支
+ await runGitCommand(`git checkout ${currentBranch}`, workspaceRoot);
+
+ await runGitCommand(`git stash pop`, workspaceRoot);
+
+ vscode.window.showInformationMessage(
+ `修改已提交到分支 ${targetBranch},提交哈希:${commitHash}`,
+ );
+ return commitHash;
+ } catch (error) {
+ vscode.window.showErrorMessage(`操作失败: ${error}`);
+ return undefined;
+ }
+}
diff --git a/client/src/codeScan/codeScanManager.ts b/client/src/codeScan/codeScanManager.ts
index d4b4b27..5882ed4 100644
--- a/client/src/codeScan/codeScanManager.ts
+++ b/client/src/codeScan/codeScanManager.ts
@@ -27,6 +27,7 @@ import { ReportMgrLoadParams } from "../../../common/src/types/reportManager";
import { ScanServerConfig } from "../types/codeScan";
import { GitUtility } from "../utils/git";
import { ClientLogger } from "../utils/log";
+import { commitToCodeScanBranch } from "./codeCommit";
import { demoData } from "./demoData";
const logger = ClientLogger.getLogger("CodeScanManager");
@@ -53,7 +54,7 @@ export class CodeScanManager {
context.subscriptions.push(
// 注册命令 代码扫描:开始扫描
- vscode.commands.registerCommand(CommandID.codeScanStart, () => {
+ vscode.commands.registerCommand(CommandID.codeScanStart, async () => {
this._instance.startScan();
}),
);
@@ -83,6 +84,9 @@ export class CodeScanManager {
// TODO: 当打开的存储库数量多于一个时,让用户选择存储库
// TODO: 检查工作区 .vscode/archive.tar.gz 是否可写
+ const commitId = await commitToCodeScanBranch();
+ logger.info(`Commit id: ${commitId}. Use this to generate archive and patch`);
+
// ======== FOR DEMO USE ONLY ========
const sleep = (time: number) => {
return new Promise((resolve) => {
@@ -118,14 +122,14 @@ export class CodeScanManager {
resolve();
}
- await sleep(2000);
+ await sleep(200);
progress.report({
message: vscode.l10n.t("Uploading archive..."),
increment: 20,
});
- await sleep(1500);
+ await sleep(150);
fs.unlinkSync(archivePath.fsPath);
@@ -134,30 +138,31 @@ export class CodeScanManager {
increment: 20,
});
- await sleep(3000);
+ await sleep(300);
progress.report({
message: vscode.l10n.t("Server finalizing report..."),
increment: 20,
});
- await sleep(1000);
+ await sleep(100);
progress.report({
message: vscode.l10n.t("Downloading report..."),
increment: 20,
});
- await sleep(1500);
+ await sleep(150);
progress.report({
message: vscode.l10n.t("Loading report..."),
increment: 20,
});
- await sleep(500);
+ await sleep(50);
// 通知 Language Server 读取报告
+ // const reportUri = vscode.Uri.joinPath(workspace.uri, "example-hint.json");
const reportUri = vscode.Uri.joinPath(workspace.uri, "example2.json");
this._client.sendNotification(LSPNotificationID.reportMgrSrvLoad, {
workspaceUri: workspace.uri.toString(),
@@ -165,7 +170,7 @@ export class CodeScanManager {
reloadConfirm: false,
});
- await sleep(500);
+ await sleep(50);
resolve();
});
diff --git a/common/src/types/report.ts b/common/src/types/report.ts
index ddb0c36..31fa9fd 100644
--- a/common/src/types/report.ts
+++ b/common/src/types/report.ts
@@ -19,17 +19,14 @@
/** 代码问题状态 */
export enum IProblemState {
- /** 问题状态:无关 */
- unrelated = 0,
+ /** 问题状态:未解决 */
+ todo = 0,
- /** 问题状态:正常 */
- default = 1,
-
- /** 问题状态:待验证 */
- verify = 2,
+ /** 问题状态:已修改 */
+ modified = 1,
/** 问题状态:已解决 */
- solved = 3,
+ done = 2,
}
/** 代码问题类型 */
@@ -102,6 +99,15 @@ export interface SourceRange {
_unified?: boolean;
}
+/** 修复信息 */
+export interface IProblemFixInfo {
+ /** 修复区域 */
+ fixRange: SourceRange;
+
+ /** 修复内容 */
+ fixContent: string;
+}
+
/** 代码问题数据 */
export interface IProblemData {
/** 文件或目录相对路径 */
@@ -136,6 +142,9 @@ export interface IProblem {
/** 问题信息 */
data: IProblemData[];
+
+ /** 修复信息 */
+ fixInfo?: IProblemFixInfo;
}
/** RVPortingTool 代码扫描报告 */
@@ -143,6 +152,9 @@ export interface IReport {
/** 报告版本号 */
version: number;
+ /** 报告 commit ID */
+ commitId: string;
+
/** 报告最后更新毫秒时间戳 */
timestamp: number;
diff --git a/server/src/compareWithCommit.ts b/server/src/compareWithCommit.ts
new file mode 100644
index 0000000..efa43bf
--- /dev/null
+++ b/server/src/compareWithCommit.ts
@@ -0,0 +1,166 @@
+import { exec } from "child_process";
+
+function runCommand(command: string, workspaceRoot: string): Promise {
+ return new Promise((resolve, reject) => {
+ exec(command, { cwd: workspaceRoot }, (error, stdout, stderr) => {
+ if (error) {
+ console.log(`stdout: ${stdout}; stderr: ${stderr}; error.message: ${error.message}`);
+ } else {
+ console.log(`stdout: ${stdout}; stderr: ${stderr}`);
+ }
+ resolve(stdout.trim());
+ });
+ });
+}
+
+interface Change {
+ originalLineFrom: number;
+ originalLineTo: number;
+ originalColFrom: number;
+ originalColTo: number;
+ newLineFrom: number;
+ newLineTo: number;
+ newColFrom: number;
+ newColTo: number;
+}
+
+export async function compareFileWithCommit(
+ filePath: string,
+ commitId: string,
+ workspaceUri: string,
+) {
+ const stdout = await runCommand(
+ `git diff -U0 --word-diff=porcelain ${commitId} -- ${filePath}`,
+ workspaceUri,
+ );
+ console.log("Running:", `git diff -U0 --word-diff=porcelain ${commitId} -- ${filePath}`);
+ // 解析 diff 信息
+ const changes = parseGitDiff(stdout);
+ console.log("Changes:", changes);
+ return changes;
+}
+
+function parseGitDiff(
+ diffOutput: string,
+): [Map, Set, Map>] {
+ const lineOffset = new Map();
+ const colOffset = new Map>();
+ const deletedLines = new Set();
+ const lines = diffOutput.split("\n");
+ let i = 0;
+
+ while (i < lines.length) {
+ const line = lines[i++];
+
+ if (
+ line.startsWith("diff --git") ||
+ line.startsWith("index") ||
+ line.startsWith("---") ||
+ line.startsWith("+++")
+ ) {
+ i++;
+ continue;
+ }
+
+ // 检查是否为 hunk 头部
+ const hunkHeaderRegex = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
+ const hunkHeaderMatch = line.match(hunkHeaderRegex);
+
+ if (hunkHeaderMatch) {
+ const originalStartLine = parseInt(hunkHeaderMatch[1], 10);
+ const originalLineCount = hunkHeaderMatch[2] ? parseInt(hunkHeaderMatch[2], 10) : 1;
+ const newStartLine = parseInt(hunkHeaderMatch[3], 10);
+ const newLineCount = hunkHeaderMatch[4] ? parseInt(hunkHeaderMatch[4], 10) : 1;
+
+ if (originalLineCount === 0) {
+ lineOffset.set(originalStartLine + 1, newStartLine + newLineCount - originalStartLine - 1);
+ } else if (newLineCount === 0) {
+ lineOffset.set(
+ originalStartLine + originalLineCount,
+ newStartLine + 1 - originalStartLine - originalLineCount,
+ );
+ for (let j = originalStartLine; j < originalStartLine + originalLineCount; j++) {
+ deletedLines.add(j);
+ }
+ } else {
+ lineOffset.set(originalStartLine, newStartLine - originalStartLine);
+ }
+
+ if (originalLineCount !== 0 && newLineCount !== 0) {
+ colOffset.set(originalStartLine, new Map());
+ // console.assert(originalLineCount === newLineCount, "Line count mismatch");
+ let lineNum = 0;
+ let colIndex = 0;
+ while ((lineNum < originalLineCount || lineNum < newLineCount) && i < lines.length) {
+ let lineContent = lines[i++];
+ if (lineContent.startsWith("~")) {
+ lineNum += 1;
+ colIndex = 0;
+ } else if (lineContent.startsWith("-")) {
+ const originalItemLength = lineContent.length - 1;
+ const nextLine = lines[i++];
+ if (nextLine.startsWith("+")) {
+ const newItemLength = nextLine.length - 1;
+ colOffset
+ .get(originalStartLine)
+ ?.set(colIndex + 1, newItemLength - originalItemLength);
+ colIndex += originalItemLength;
+ } else {
+ colOffset.get(originalStartLine)?.set(colIndex + 1, -originalItemLength);
+ }
+ } else {
+ colIndex += lineContent.length - 1;
+ }
+ }
+ if (!colOffset.get(originalStartLine)?.has(0)) {
+ colOffset.get(originalStartLine)?.set(0, 0);
+ }
+ }
+ }
+ }
+
+ if (!lineOffset.has(0)) {
+ lineOffset.set(0, 0);
+ }
+ return [lineOffset, deletedLines, colOffset];
+}
+
+function compareLines(
+ originalLine: string,
+ newLine: string,
+ originalLineNum: number,
+ newLineNum: number,
+): Change {
+ // 简单比较两个字符串,找到变化的位置
+ let startIndex = 0;
+ while (
+ startIndex < originalLine.length &&
+ startIndex < newLine.length &&
+ originalLine[startIndex] === newLine[startIndex]
+ ) {
+ startIndex++;
+ }
+
+ let originalEndIndex = originalLine.length - 1;
+ let newEndIndex = newLine.length - 1;
+ while (
+ originalEndIndex >= startIndex &&
+ newEndIndex >= startIndex &&
+ originalLine[originalEndIndex] === newLine[newEndIndex]
+ ) {
+ originalEndIndex--;
+ newEndIndex--;
+ }
+
+ const change: Change = {
+ originalLineFrom: originalLineNum,
+ originalLineTo: originalLineNum,
+ originalColFrom: startIndex + 1,
+ originalColTo: originalEndIndex + 2,
+ newLineFrom: newLineNum,
+ newLineTo: newLineNum,
+ newColFrom: startIndex + 1,
+ newColTo: newEndIndex + 2,
+ };
+ return change;
+}
diff --git a/server/src/reportManager.ts b/server/src/reportManager.ts
index 2f2e1a4..8f384ce 100644
--- a/server/src/reportManager.ts
+++ b/server/src/reportManager.ts
@@ -21,8 +21,9 @@
import Ajv, * as ajv from "ajv";
import * as fs from "fs";
import * as mkdirp from "mkdirp";
+import * as lsp from "vscode-languageserver";
import { URI } from "vscode-uri";
-import { IReport } from "../../common/src/types/report";
+import { IProblem, IReport } from "../../common/src/types/report";
import {
ReportMgrLoadError,
ReportMgrLoadErrorType,
@@ -31,7 +32,7 @@ import {
ReportMgrSaveParams,
} from "../../common/src/types/reportManager";
import { ReportMeta } from "../../common/src/types/reportMeta";
-import { TextDocChangeParams, updateReportByTextDocumentChange } from "./reportTransformer";
+import { TextDocChangeParams } from "./reportTransformer";
import { ServerLogger } from "./utils/log";
import path = require("path");
import strFormat = require("string-format");
@@ -51,9 +52,80 @@ export class ReportManager {
* key 为工作区的 Uri 文本
*/
private _reportMetaMap: Map;
+ private _diagnosticPDataMap: Map;
constructor() {
this._reportMetaMap = new Map();
+ this._diagnosticPDataMap = new Map();
+ }
+
+ /**
+ * 添加报告
+ *
+ * @param connection LSP 连接
+ * @param diagnostics 诊断信息列表
+ * @param pData 诊断信息列表对应的问题数据
+ * @param reportUri 报告 Uri
+ * @param version 报告版本
+ */
+ public async addDiagnostics(
+ connection: lsp.Connection,
+ diagnostics: lsp.Diagnostic[],
+ reportProblems: IProblem[],
+ reportUri: string,
+ version: number,
+ ): Promise {
+ if (diagnostics.length !== reportProblems.length) {
+ logger.error("addDiagnostics: diagnostics and pData length not equal");
+ return;
+ }
+ for (let i = 0; i < diagnostics.length; i++) {
+ this._diagnosticPDataMap.set(
+ this.generateDiagnosticKey(diagnostics[i], reportUri),
+ reportProblems[i],
+ );
+ }
+ await connection.sendDiagnostics({
+ uri: reportUri,
+ version: version,
+ diagnostics: diagnostics,
+ });
+ }
+
+ public async clearDiagnostics(connection: lsp.Connection, reportUri: string): Promise {
+ const currentDiagnostics = await connection.sendRequest("diagnostics", {
+ uri: reportUri,
+ });
+ for (const diagnostic of currentDiagnostics) {
+ this._diagnosticPDataMap.delete(this.generateDiagnosticKey(diagnostic, reportUri));
+ }
+ await connection.sendDiagnostics({
+ uri: reportUri,
+ version: 1,
+ diagnostics: [],
+ });
+ }
+
+ private generateDiagnosticKey(diagnostic: lsp.Diagnostic, uri: string): string {
+ // 获取诊断的必要信息
+ const range = diagnostic.range;
+ const startLine = range.start.line;
+ const startChar = range.start.character;
+ const endLine = range.end.line;
+ const endChar = range.end.character;
+ const code = diagnostic.code || ""; // 有些诊断可能没有 code
+ const source = diagnostic.source || ""; // 有些诊断可能没有 source
+ const message = diagnostic.message || ""; // 有些诊断可能没有 message
+
+ // 生成唯一键
+ const key = `${uri}:${startLine}:${startChar}:${endLine}:${endChar}:${code}:${source}:${message}`;
+
+ // 返回生成的键
+ return key;
+ }
+
+ public getReportProblem(diagnostic: lsp.Diagnostic, uri: string): IProblem | undefined {
+ return this._diagnosticPDataMap.get(this.generateDiagnosticKey(diagnostic, uri));
}
/**
@@ -427,6 +499,6 @@ export class ReportManager {
*/
public applyChanges(reportMeta: ReportMeta, change: TextDocChangeParams) {
// TODO: Report transform
- updateReportByTextDocumentChange(reportMeta, change);
+ // updateReportByTextDocumentChange(reportMeta, change);
}
}
diff --git a/server/src/reportManagerServer.ts b/server/src/reportManagerServer.ts
index f22138b..0dd21b5 100644
--- a/server/src/reportManagerServer.ts
+++ b/server/src/reportManagerServer.ts
@@ -18,6 +18,7 @@
* Last Change: Sep 11, 2024
**************************************************************************************/
+import { CodeAction, CodeActionKind, TextDocumentSyncKind } from "vscode-languageserver";
import { TextDocument } from "vscode-languageserver-textdocument";
import * as lsp from "vscode-languageserver/node";
import { URI } from "vscode-uri";
@@ -135,6 +136,14 @@ export class ReportManagerServer {
manager.refreshDiagnostics(e.document);
});
+ documents.onDidSave((e) => {
+ if (manager._currDocument !== e.document) {
+ manager._currDocument = e.document;
+ logger.debug("documents.onDidSave: ".concat(e.document.uri));
+ }
+ manager.refreshDiagnostics(e.document);
+ });
+
// 加载已有 Workspace 下缓存的报告
connection.workspace.getWorkspaceFolders().then((workspaces) => {
workspaces?.forEach((workspace) => {
@@ -142,6 +151,72 @@ export class ReportManagerServer {
});
manager.refreshDiagnostics();
});
+
+ connection.onInitialize((params) => {
+ return {
+ capabilities: {
+ textDocumentSync: TextDocumentSyncKind.Full,
+ codeActionProvider: {
+ codeActionKinds: [CodeActionKind.QuickFix],
+ },
+ },
+ };
+ });
+ // 监听 CodeAction
+ connection.onCodeAction((params) => {
+ const actions: CodeAction[] = [];
+ for (const diagnostic of params.context.diagnostics) {
+ const problem = manager._reportManager.getReportProblem(
+ diagnostic,
+ params.textDocument.uri,
+ );
+ if (problem === undefined) {
+ logger.error("onCodeAction: can't find problem by diagnostic");
+ continue;
+ }
+ if (problem.fixInfo === undefined) {
+ logger.info("onCodeAction: problem has no fix info");
+ continue;
+ }
+ const fix = {
+ title: "RvScan",
+ kind: CodeActionKind.QuickFix,
+ diagnostics: [diagnostic],
+ edit: {
+ changes: {
+ [params.textDocument.uri]: [
+ {
+ range: {
+ start: {
+ line: problem.fixInfo.fixRange.lineFrom - 1,
+ character: problem.fixInfo.fixRange.colFrom,
+ },
+ end: {
+ line: problem.fixInfo.fixRange.lineUpto! - 1,
+ character: problem.fixInfo.fixRange.colUpto,
+ },
+ },
+ newText: problem.fixInfo.fixContent,
+ },
+ ],
+ },
+ command: {
+ title: "RvScan",
+ command: "refreshDiagnostics",
+ arguments: [params.textDocument.uri],
+ },
+ },
+ };
+ actions.push(fix);
+ }
+ return actions;
+ });
+
+ connection.onRequest("refreshDiagnostics", (uri: string) => {
+ // 重新发送原来的诊断信息
+ manager.refreshDiagnostics(manager._documents.get(uri));
+ });
+
return manager;
}
@@ -373,11 +448,7 @@ export class ReportManagerServer {
const reportMeta = this._reportManager.getReportMeta(docUri);
if (!reportMeta) {
// 清空当前所有报告
- await this._connection.sendDiagnostics({
- uri: docUri.toString(),
- version: 1,
- diagnostics: [],
- });
+ this._reportManager.clearReport(docUri);
return;
}
const settings =
@@ -390,6 +461,7 @@ export class ReportManagerServer {
settings,
textDocument,
reportMeta,
+ this._reportManager,
);
}
}
diff --git a/server/src/reportToDiagnostic.ts b/server/src/reportToDiagnostic.ts
index 0ff0d71..df06678 100644
--- a/server/src/reportToDiagnostic.ts
+++ b/server/src/reportToDiagnostic.ts
@@ -22,8 +22,11 @@ import * as TextDoc from "vscode-languageserver-textdocument";
import { URI } from "vscode-uri";
import { CommandID } from "../../common/src/types/command";
import { RVCodingAsstConfig } from "../../common/src/types/extConfig";
+import { IProblemState, SourceRange } from "../../common/src/types/report";
import { ReportMeta } from "../../common/src/types/reportMeta";
import { LSPRequestID } from "../../common/src/types/request";
+import { compareFileWithCommit } from "./compareWithCommit";
+import { ReportManager } from "./reportManager";
import path = require("path");
interface RuleInfo {
@@ -39,12 +42,65 @@ export interface DiagnosticCodeExternal {
export type DiagnosticCode = string | number | DiagnosticCodeExternal | undefined;
+function findLowestValue(map: Map, key: number): number {
+ let lowestKey = 0;
+
+ for (let k of map.keys()) {
+ if (k <= key && k > lowestKey) {
+ lowestKey = k;
+ }
+ }
+ return map.get(lowestKey) ?? 0;
+}
+
+function calculateNewSourceRange(
+ srcRange: SourceRange,
+ changes: [Map, Set, Map>],
+): SourceRange {
+ const [lineOffset, deletedLines, colOffset] = changes;
+ let originalLineFrom = srcRange.lineFrom;
+ let originalLineTo = srcRange.lineUpto;
+ const newSrcRange = { ...srcRange };
+
+ if (originalLineFrom in deletedLines) {
+ while (originalLineFrom in deletedLines) {
+ originalLineFrom--;
+ }
+ const newLineFrom = originalLineFrom + findLowestValue(lineOffset, originalLineFrom);
+ newSrcRange.lineFrom = newLineFrom;
+ newSrcRange.colFrom = 9999999;
+ } else {
+ newSrcRange.lineFrom = originalLineFrom + findLowestValue(lineOffset, originalLineFrom);
+ if (srcRange.colFrom !== undefined)
+ if (colOffset.has(originalLineFrom))
+ newSrcRange.colFrom =
+ srcRange.colFrom! + findLowestValue(colOffset.get(originalLineFrom)!, srcRange.colFrom!);
+ }
+ if (originalLineTo !== undefined) {
+ if (originalLineTo in deletedLines) {
+ while (originalLineTo in deletedLines) {
+ originalLineTo--;
+ }
+ const newLineUpto = originalLineTo + findLowestValue(lineOffset, originalLineTo);
+ newSrcRange.lineUpto = newLineUpto;
+ newSrcRange.colUpto = 9999999;
+ } else {
+ newSrcRange.lineUpto = originalLineTo + findLowestValue(lineOffset, originalLineTo);
+ if (srcRange.colUpto !== undefined && colOffset.has(originalLineTo))
+ newSrcRange.colUpto =
+ srcRange.colUpto! + findLowestValue(colOffset.get(originalLineTo)!, srcRange.colUpto!);
+ }
+ }
+ return newSrcRange;
+}
+
export async function refreshDocumentDiagnostics(
connection: lsp.Connection,
hasDiagRelInfoCapability: boolean,
extConfig: RVCodingAsstConfig,
document: TextDoc.TextDocument,
reportMeta: ReportMeta,
+ reportManager: ReportManager,
) {
const workspaceUri = reportMeta.workspaceUri;
const docUri: URI = URI.parse(document.uri);
@@ -52,6 +108,7 @@ export async function refreshDocumentDiagnostics(
const workspaceRootPath = workspaceUri.fsPath;
const problems = reportMeta.reportData.problems;
+ const diagProblems = [];
// 所有诊断数据
const diags: lsp.Diagnostic[] = [];
@@ -73,10 +130,24 @@ export async function refreshDocumentDiagnostics(
// 对于源码级问题,problem.data 每一个元素视为一个诊断
for (let pbData of problem.data) {
i++;
- const srcRange = pbData.srcRange;
- if (!srcRange || srcRange.hidden) {
+ const originalSrcRange = pbData.srcRange;
+ if (!originalSrcRange) {
continue;
}
+
+ const changes = await compareFileWithCommit(
+ docUri.fsPath,
+ reportMeta.reportData.commitId,
+ workspaceUri.fsPath,
+ );
+
+ let srcRange = undefined;
+ if (!changes) {
+ srcRange = originalSrcRange;
+ } else {
+ srcRange = calculateNewSourceRange(originalSrcRange, changes);
+ }
+
const fileUri = URI.file(path.resolve(workspaceRootPath, srcRange.filePath));
if (fileUri.toString() !== docUri.toString()) {
continue;
@@ -119,6 +190,13 @@ export async function refreshDocumentDiagnostics(
desc += ": ";
}
desc += pbData.desc;
+
+ let stateMsg = "[无状态]";
+ if (problem.state === IProblemState.todo) stateMsg = "[💥未解决]";
+ else if (problem.state === IProblemState.modified) stateMsg = "[❓已修改]";
+ else if (problem.state === IProblemState.done) stateMsg = "[✅已解决]";
+
+ desc = stateMsg + " " + desc;
mainDiag = lsp.Diagnostic.create(
lspRange,
desc,
@@ -134,15 +212,18 @@ export async function refreshDocumentDiagnostics(
problem.checkerId,
[],
);
+ diagProblems.push(problem);
}
}
if (mainDiag) {
diags.push(mainDiag);
}
}
- await connection.sendDiagnostics({
- uri: docUri.toString(),
- version: reportMeta.reportData.version,
- diagnostics: diags,
- });
+ reportManager.addDiagnostics(
+ connection,
+ diags,
+ diagProblems,
+ docUri.toString(),
+ reportMeta.reportData.version,
+ );
}
diff --git a/server/src/server.ts b/server/src/server.ts
index 0defe3b..e9dc0b0 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -69,6 +69,7 @@ connection.onInitialize((params: lsp.InitializeParams) => {
// completionProvider: {
// resolveProvider: true,
// },
+ codeActionProvider: true,
},
};
if (clientCapabilities.hasWorkspaceFolderCapability) {
diff --git a/testRoot/.gitignore b/testRoot/.gitignore
new file mode 100644
index 0000000..8feace6
--- /dev/null
+++ b/testRoot/.gitignore
@@ -0,0 +1 @@
+rvCodingAsst_report.json
\ No newline at end of file
diff --git a/testRoot/example-hint.json b/testRoot/example-hint.json
new file mode 100644
index 0000000..03ebe3d
--- /dev/null
+++ b/testRoot/example-hint.json
@@ -0,0 +1,366 @@
+{
+ "version": 1,
+ "timestamp": 1725170530000,
+ "problems": [
+ {
+ "id": "000001",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 12,
+ "lineUpto": 7,
+ "colUpto": 20,
+ "comment": "__i386__"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000002",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 32,
+ "lineUpto": 7,
+ "colUpto": 42,
+ "comment": "__x86_64__"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000003",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 54,
+ "lineUpto": 7,
+ "colUpto": 60,
+ "comment": "__i386"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000004",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 12,
+ "lineUpto": 8,
+ "colUpto": 20,
+ "comment": "__x86_64"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000005",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 32,
+ "lineUpto": 8,
+ "colUpto": 39,
+ "comment": "_M_IX86"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000006",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 51,
+ "lineUpto": 8,
+ "colUpto": 59,
+ "comment": "_M_IX86"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000007",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0003",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 9,
+ "colFrom": 10,
+ "lineUpto": 9,
+ "colUpto": 22,
+ "comment": "RETURN_INSTR"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 12,
+ "lineUpto": 7,
+ "colUpto": 20,
+ "comment": "在 X86 架构特有宏下定义: __i386__"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 32,
+ "lineUpto": 7,
+ "colUpto": 42,
+ "comment": "在 X86 架构特有宏下定义: __x86_64__"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 7,
+ "colFrom": 54,
+ "lineUpto": 7,
+ "colUpto": 60,
+ "comment": "在 X86 架构特有宏下定义: __i386"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 12,
+ "lineUpto": 8,
+ "colUpto": 20,
+ "comment": "在 X86 架构特有宏下定义: __x86_64"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 32,
+ "lineUpto": 8,
+ "colUpto": 39,
+ "comment": "在 X86 架构特有宏下定义: _M_IX86"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 8,
+ "colFrom": 51,
+ "lineUpto": 8,
+ "colUpto": 59,
+ "comment": "在 X86 架构特有宏下定义: _M_IX86"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000008",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0001",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 11,
+ "colFrom": 14,
+ "lineUpto": 11,
+ "colUpto": 21,
+ "comment": "__arm__"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000009",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0001",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 11,
+ "colFrom": 33,
+ "lineUpto": 11,
+ "colUpto": 39,
+ "comment": "_M_ARM"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000010",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0002",
+ "level": 4,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 12,
+ "colFrom": 10,
+ "lineUpto": 12,
+ "colUpto": 22,
+ "comment": "_M_ARM"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 11,
+ "colFrom": 14,
+ "lineUpto": 11,
+ "colUpto": 21,
+ "comment": "在 ARM 架构特有宏下定义: __arm__"
+ }
+ },
+ {
+ "path": "example2.c",
+ "desc": "",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 11,
+ "colFrom": 33,
+ "lineUpto": 11,
+ "colUpto": 39,
+ "comment": "在 ARM 架构特有宏下定义: _M_ARM"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000011",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0008",
+ "level": 2,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "缺少针对 RISC-V 架构的分支条件",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 14,
+ "colFrom": 0,
+ "lineUpto": 14,
+ "colUpto": 6,
+ "comment": "缺少针对 RISC-V 架构的分支条件"
+ }
+ }
+ ]
+ },
+ {
+ "id": "000012",
+ "state": 0,
+ "checkerId": "c_cxx",
+ "type": "source",
+ "ruleId": "CC-0005",
+ "level": 1,
+ "data": [
+ {
+ "path": "example2.c",
+ "desc": "未受架构特有宏保护的内联汇编代码",
+ "srcRange": {
+ "filePath": "example2.c",
+ "lineFrom": 18,
+ "colFrom": 0,
+ "lineUpto": 22,
+ "colUpto": 37,
+ "comment": "未受架构特有宏保护的内联汇编代码"
+ }
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/testRoot/example2.c b/testRoot/example2.c
index ede4e40..b65b9ad 100644
--- a/testRoot/example2.c
+++ b/testRoot/example2.c
@@ -4,7 +4,7 @@
* can be enough.
*/
-#if defined __i386__ || defined __x86_64__ || defined __i386 || \
+#if defined __i38Changes6__ || defined __x86_64__ || defined __i386 || \
defined __x86_64 || defined _M_IX86 || defined _M_AMD64
# define RETURN_INSTR 0xC3C3C3C3 /* ret; ret; ret; ret */
@@ -21,3 +21,4 @@ __asm__ volatile ("mov eax, 5\n"
"add eax, 6\n"
"mov result, eax");
#endif
+
diff --git a/testRoot/example2.json b/testRoot/example2.json
index 891419d..af21bd0 100644
--- a/testRoot/example2.json
+++ b/testRoot/example2.json
@@ -1,10 +1,11 @@
{
"version": 1,
"timestamp": 1725170530000,
+ "commitId": "cc8bfe6e407e01f274a82604f2647e70d28f4768",
"problems": [
{
"id": "000001",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0003",
@@ -26,7 +27,7 @@
},
{
"id": "000002",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0003",
@@ -48,7 +49,7 @@
},
{
"id": "000003",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0003",
@@ -70,7 +71,7 @@
},
{
"id": "000004",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0003",
@@ -92,7 +93,7 @@
},
{
"id": "000005",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0003",
@@ -114,7 +115,7 @@
},
{
"id": "000006",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0003",
@@ -136,7 +137,7 @@
},
{
"id": "000007",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0003",
@@ -230,7 +231,7 @@
},
{
"id": "000008",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0001",
@@ -252,7 +253,7 @@
},
{
"id": "000009",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0001",
@@ -274,7 +275,7 @@
},
{
"id": "000010",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0002",
@@ -320,7 +321,7 @@
},
{
"id": "000011",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0008",
@@ -342,7 +343,7 @@
},
{
"id": "000012",
- "state": 1,
+ "state": 0,
"checkerId": "c_cxx",
"type": "source",
"ruleId": "CC-0005",
@@ -360,7 +361,17 @@
"comment": "未受架构特有宏保护的内联汇编代码"
}
}
- ]
+ ],
+ "fixInfo": {
+ "fixRange": {
+ "filePath": "example2.c",
+ "lineFrom": 18,
+ "colFrom": 0,
+ "lineUpto": 22,
+ "colUpto": 37
+ },
+ "fixContent": "FIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\nFIXED CONTENT\n"
+ }
}
]
-}
+}
\ No newline at end of file
--
Gitee