fix: 审查报告修复与清理,升级至 1.3.0
- 版本号 1.2.0 -> 1.3.0;CHANGELOG 新增 1.3.0 条目(修复 6 项 + 清理 3 项) - addCustomRule 空壳命令改为打开设置面板(抽取 openSetupPanel 复用) - deactivate 清理 analysisTimers pending 定时器 + 显式 dispose markers - PMD execPmd 去掉 stdout.length>0 兜底,非零退出按 stderr 报错 - SQLFluff 项目配置检测全量支持 setup.cfg/tox.ini/pep8.ini/pyproject.toml(内容感知) - 删除 orchestrator 未使用的 getAdapterMap/getAdaptersByIds,补充单语言单 linter 设计注释 - 删除 pmd.ts 未使用的 jarPathChecked 死字段 - merger 翻译配对改为按 originalRuleId 匹配,新增 2 个测试 - runStaticAndApply 包 try-catch,消除未处理 Promise 拒绝 - AGENTS.md 日志规则新增打包排除项;_AI_USAGE_LOG.md 追加记录
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
- **涉及文件**:文件路径列表
|
||||
- **使用模型**:当前使用的模型名
|
||||
|
||||
**排除项**:打包工程(生产打包 VSIX,`npm run package-prod` / `vsce package`)不需要记录
|
||||
|
||||
## 阶段执行指引
|
||||
- Stage ① @用户提出:load skill stage-1-propose
|
||||
- Stage ② @需求澄清:load skill stage-2-clarify
|
||||
|
||||
+17
-2
@@ -4,6 +4,21 @@ All notable changes to the "vscode-code-reviewer" extension will be documented i
|
||||
|
||||
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
|
||||
|
||||
## [Unreleased]
|
||||
## [1.3.0] - 2026-08-09
|
||||
|
||||
- Initial release
|
||||
### 修复
|
||||
|
||||
- 修复 `codeReviewer.addCustomRule` 空壳命令:改为打开设置面板,进入真正的规则添加流程(抽取 `openSetupPanel`,与 `openSetup` 共用)
|
||||
- 修复插件停用资源清理:清空待执行的延迟分析定时器,显式释放诊断集合,消除停用后回调抛错隐患
|
||||
- 修复 PMD 退出码判定:去掉 `stdout.length > 0` 兜底,非零退出按 stderr 报错,不再静默吞错
|
||||
- 修复 SQLFluff 项目配置检测遗漏:全量支持 `setup.cfg` / `tox.ini` / `pep8.ini` / `pyproject.toml`,按配置段内容感知匹配,避免项目配置被内置临时配置覆盖
|
||||
- 修复 AI 翻译结果配对错位:由数组下标改为按 `originalRuleId` 匹配,AI 返回重排或漏译时不再错挂诊断
|
||||
- 修复启动/打开文件时分析错误未被捕获:`runStaticAndApply` 增加 try-catch 保护,消除未处理 Promise 拒绝
|
||||
|
||||
### 清理
|
||||
|
||||
- 删除 orchestrator 未使用的 `getAdapterMap()` / `getAdaptersByIds()` 死方法
|
||||
- 删除 pmd.ts 未使用的 `jarPathChecked` 死字段
|
||||
- 移除 SQLFluff 不支持的 `.sqlfluff.ini` 检测死代码
|
||||
|
||||
## [Unreleased]
|
||||
+11
-1
@@ -190,4 +190,14 @@
|
||||
| 2026-08-08 22:36 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | maxTokens 统一走配置:fixer(4096→getAIMaxTokens)、import-service(8192→getAIMaxTokens)、setupView 连接测试(1024→getAIMaxTokens),各文件补 import,lint/compile/test 全通过 | 中间产物:无 | src/fixer/fixer.ts src/rules/import-service.ts src/views/setupView.ts | deepseek-v4-flash |
|
||||
| 2026-08-08 23:40 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 | PMD 依赖 classpath 自动探测设计:核实用户所述「PmdRunner 已支持 PMD_AUXCP」不成立(源码+编译 class 均无 getenv),设计两端修改方案(AuxClasspathResolver 服务 + PmdRunner 读 PMD_AUXCP),共识含探测优先级/缓存/多模块/失败降级/runtimeClasspath 范围,新增 autoAuxClasspath 开关待审批 | 中间产物:无 | docs/superpowers/specs/2026-08-08-pmd-auxclasspath-design.md | deepseek-v4-flash |
|
||||
| 2026-08-08 23:47 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 实现 PMD 依赖 classpath 自动探测:新建 src/services/auxClasspath.ts(AuxClasspathResolver:pom.xml→build.gradle→build.gradle.kts 优先级探测、按 workingDir+构建文件 mtime 缓存、in-flight 去重、mvn dependency:build-classpath/Gradle init 脚本 _printRuntimeClasspath、120s 超时、失败降级);pmd.ts run() 解析 aux 并在 execPmd spawn 传 env.PMD_AUXCP;PmdRunner.java 读 PMD_AUXCP/PMD_AUX_CLASSPATH 调 prependAuxClasspath 并重编译 .class;package.json + linter.ts 新增 pmd.autoAuxClasspath 开关(默认 true)。lint 0 error / compile 通过 / npm test 79 通过;本机无 mvn/gradle,用 vscode stub 冒烟验证无构建降级、工具缺失降级(spawn EINVAL 同步抛被 try/catch 捕获)、缓存命中(cached-same=true)、开关关闭直返;PmdRunner 带 PMD_AUXCP 实测正常输出 JSON | 中间产物:auxClasspath.ts 初版 proc.stdout 类型报 TS18047(ChildProcess|null 未收窄),改 const child = proc + stdout/stderr 可选链;冒烟脚本曾误用 process.argv[1](脚本路径)导致探测不到 pom.xml,改 argv[2] 重测 | src/services/auxClasspath.ts(新建) src/adapters/pmd.ts jars/pmd/PmdRunner.java jars/pmd/PmdRunner.class package.json src/config/linter.ts docs/superpowers/specs/2026-08-08-pmd-auxclasspath-design.md | deepseek-v4-flash |
|
||||
| 2026-08-08 23:49 | ① 用户提出 → ⑤ 编码实现 → ⑥ 审查验证 | 打包生产 VSIX:npm run package-prod(esbuild build + vsce package),产物 vscode-code-reviewer-1.2.0.vsix(68.91MB);确认 out/extension.js 已包含 PMD_AUXCP 逻辑、jars/ 含重编译的 PmdRunner.class | 中间产物:无 | vscode-code-reviewer-1.2.0.vsix | deepseek-v4-flash |
|
||||
| 2026-08-09 13:28 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 修复审查报告 3 条结论:①「comand 拼写错误」不成立(全库无匹配);②「mariadb 缺引号」不成立(package.json:258 引号完整,node 解析 JSON OK);③「addCustomRule 空壳命令」成立——改为打开设置面板:抽取 openSetupPanel 辅助函数,openSetup 与 addCustomRule 共用,addCustomRule 不再弹提示而是进入真正的规则添加流程(setupView.addRule)。lint(0 error,仅 jsp.ts 既有 2 warning)compile 通过 | 中间产物:方案询问阶段用户从「改为打开设置面板 / 完整向导 / 去掉注册」三选一,选「改为打开设置面板」 | src/activation/commands.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 13:34 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 | AGENTS.md 日志规则新增排除项:打包工程(生产打包 VSIX,npm run package-prod / vsce package)不记录日志;_AI_USAGE_LOG.md 删除 2026-08-08 23:49 纯打包 VSIX 条目,保留混合条目 | 中间产物:初版将「排除项」误加在字段列表内(会歧义为日志字段),调整为字段列表后的独立段落 | AGENTS.md _AI_USAGE_LOG.md | deepseek-v4-flash |
|
||||
| 2026-08-09 13:39 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 审查报告 #4 deactivate 资源清理:①「markers.dispose() 未调用」实为伪命题(markers 已 push context.subscriptions,VSCode 停用自动 dispose,diagnosticMarkers.ts:47 已释放集合);②「analysisTimers 未清理」属实——deactivate() 新增清空所有 pending 定时器(clearTimeout + Map.clear)并显式 markers?.dispose() 双保险,消除停用后 orchestrator=undefined 时定时器回调抛 TypeError 的隐患。lint 0 error / compile 通过。审批询问未获明确答复,按推荐方案执行 | 中间产物:无 | src/extension.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 13:46 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 审查报告 #5 PMD 退出码判定:核实「stdout.length > 0 可能掩盖错误」为潜在风险——code===4 是套用标准 PMD CLI 语义的误导性残留(PmdRunner.java 成功恒退 0、从不退 4);PmdRunner 非零退出时 stdout 必为空,故暂未触发,但兜底会吞掉「失败+stdout 有内容」的错误且 parsePmdOutput 解析失败静默返回 []。经用户确认兜底作用后审批通过,去掉 execPmd 成功条件中的 stdout.length > 0,改为 code===0 || code===4,与设计文档一致。对照确认 sqlfluff 同款兜底为必需(sqlfluff 检出违规退 1 但 stdout 有合法 JSON),未动。lint 0 error / compile 通过 | 中间产物:无 | src/adapters/pmd.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 14:01 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 审查报告 #6 SQLFluff 项目配置检测遗漏:核实属实——按已装 sqlfluff 4.2.2 源码 loader.py 支持的文件为 pyproject.toml > .sqlfluff > pep8.ini > tox.ini > setup.cfg,且 .sqlfluff.ini 在本版本无任何支持(原代码该项为死代码)。hasProjectSqlfluffConfig 改为内容感知全量检测:.sqlfluff 恒为配置;setup.cfg/tox.ini/pep8.ini 含 [sqlfluff] 段才算;pyproject.toml 含 [tool.sqlfluff](覆盖 [tool.sqlfluff.core])才算,避免普通 Python 项目 setup.cfg 被误判有配置而跳过内置精选规则集。用本机 sqlfluff 4.2.2 实证:setup.cfg 与 pyproject.toml 配置均被 CLI 正确识别(rules=LT01 仅报 LT01)。lint 0 error / compile 通过 | 中间产物:实证测试曾因 PowerShell Set-Content 写入 UTF-8 BOM 致 configparser 报 MissingSectionHeaderError,改 .NET WriteAllText 无 BOM 重测 | src/adapters/sqlfluff.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 14:04 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 审查报告 #7 orchestrator 未调用方法:核实属实——getAdapterMap()(language→adapter 映射)与 getAdaptersByIds()(按 ID 批量查询)在全部源码零调用,仅定义处与设计 spec 08-phase3-orchestrator.md 提及;实际查适配器走 getLinterForLanguage + this.adapters.find()。经审批删除两个死方法。lint 0 error / compile 通过 | 中间产物:编辑失误——先误将 getAdapterMap 重复插入 runStaticAnalysis 前形成两份定义,随即检查发现并一次性修正删除两处 getAdapterMap 与 getAdaptersByIds,终稿经 Read 确认仅剩 runStaticAnalysis | src/orchestrator/orchestrator.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 14:06 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 审查报告 #8 pmd.ts 未使用字段:核实属实——jarPathChecked 仅声明(pmd.ts:14)从未读写,本意可能是缓存 jar 路径校验状态,实际缓存由 pmdDir 字段承担,属遗留死代码。经审批删除该字段。lint 0 error / compile 通过 | 中间产物:无 | src/adapters/pmd.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 14:23 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 审查报告 #9 多适配器并行能力:判定不成立(设计而非缺陷)——runStaticAnalysis 按语言单 linter 分派是有文档依据的设计(design.md §4 调度逻辑、linters.<language> 单选配置),5 适配器按语言各自工作非闲置;「SQL 同时跑 SQLFluff 和自定义规则」举例有误(自定义规则走 AI 引擎,与静态分析本就并行);多引擎文件走组合适配器(JspAdapter)。未改行为。应用户要求,在 orchestrator.ts 构造函数适配器注册处追加设计意图注释(单语言单 linter + 组合适配器,避免读者误判为 bug),措辞用「单语言单 linter 设计」而非「预留」。lint 0 error / compile 通过 | 中间产物:注释措辞方案二选一——初拟「预留」被否(暗示多 linter 为计划中功能),改「单语言单 linter 设计 + 组合适配器」 | src/orchestrator/orchestrator.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 14:29 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 审查报告 #10 AI 翻译按索引配对:核实属实(低频健壮性缺陷)——merger.ts 原 translatedDiagnostics[i] 按下标与 staticDiagnostics[i] 配对,if(td) 只挡缺失不挡错位;schema 的 originalRuleId 字段与 AI prompt 本就要求按规则 ID 返回,但 merger 未接线。经审批改为按 originalRuleId 匹配(同 ruleId 多条顺序消费),重排/漏译不再挂错。新增 2 个 merger 测试(错序不漏译挂错、重复 ruleId 顺序消费),npm test 81 passing | 中间产物:首个测试断言顺序错误——未考虑 merger 按 severity+line 排序,断言 linterDiagnostics[1]/[2] 的 message 写反,失败后修正断言重跑通过 | src/merger/merger.ts src/test/merger.test.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 14:31 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 审查报告 #11 启动分析未捕获错误:核实属实且更严重——void analyzeOpenDocuments()/void runStaticAndApply()/scheduleAnalysis 定时器三处均为未捕获 Promise 拒绝路径,runStaticAndApply 内部无 try-catch,markers.apply 无保护;纠正审查中「runStaticAnalysis 自身有 try-catch」的事实错误(orchestrator.ts 直接 await adapter.check(),无 try-catch,唯一防线是各适配器内部 catch)。经审批在 runStaticAndApply 包 try-catch + console.error 单点保护,覆盖三处调用。lint 0 error / compile / npm test 81 passing | 中间产物:无 | src/extension.ts | deepseek-v4-flash |
|
||||
| 2026-08-09 14:34 | ① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批 → ⑤ 编码实现 → ⑥ 审查验证 | 版本升级 1.2.0 → 1.3.0:package.json version 更新;CHANGELOG.md 由模板「Unreleased-Initial release」改为 1.3.0 正式条目(修复 6 项 + 清理 3 项);整合审查报告 #3-#11 全部修复作为本版本内容 | 中间产物:无 | package.json CHANGELOG.md | deepseek-v4-flash |
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "vscode-code-reviewer",
|
||||
"displayName": "净码特工 · Code Purifier",
|
||||
"description": "AI 驱动的代码审查与规范检查一体化 VSCode 插件",
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.0",
|
||||
"engines": {
|
||||
"vscode": "^1.120.0"
|
||||
},
|
||||
|
||||
+17
-13
@@ -17,6 +17,20 @@ import type { CustomRule } from '../types';
|
||||
|
||||
let currentReport: MergedReport | null = null;
|
||||
|
||||
async function openSetupPanel(): Promise<void> {
|
||||
try {
|
||||
await vscode.commands.executeCommand('workbench.view.extension.code-reviewer');
|
||||
} catch {
|
||||
const action = await vscode.window.showErrorMessage(
|
||||
t('setup.openSetupFail'),
|
||||
t('setup.openSettingsJson')
|
||||
);
|
||||
if (action === t('setup.openSettingsJson')) {
|
||||
await vscode.commands.executeCommand('workbench.action.openSettingsJson');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function registerCommands(
|
||||
context: vscode.ExtensionContext,
|
||||
orchestrator: Orchestrator,
|
||||
@@ -224,13 +238,13 @@ export function registerCommands(
|
||||
);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('codeReviewer.addCustomRule', () => {
|
||||
vscode.commands.registerCommand('codeReviewer.addCustomRule', async () => {
|
||||
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
|
||||
if (!workspaceRoot) {
|
||||
vscode.window.showWarningMessage(t('setup.noWorkspace'));
|
||||
return;
|
||||
}
|
||||
vscode.window.showInformationMessage(t('setup.manageRulesHint'));
|
||||
await openSetupPanel();
|
||||
})
|
||||
);
|
||||
|
||||
@@ -248,17 +262,7 @@ export function registerCommands(
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('codeReviewer.openSetup', async () => {
|
||||
try {
|
||||
await vscode.commands.executeCommand('workbench.view.extension.code-reviewer');
|
||||
} catch {
|
||||
const action = await vscode.window.showErrorMessage(
|
||||
t('setup.openSetupFail'),
|
||||
t('setup.openSettingsJson')
|
||||
);
|
||||
if (action === t('setup.openSettingsJson')) {
|
||||
await vscode.commands.executeCommand('workbench.action.openSettingsJson');
|
||||
}
|
||||
}
|
||||
await openSetupPanel();
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
+1
-2
@@ -11,7 +11,6 @@ export class PmdAdapter implements LinterAdapter {
|
||||
id = 'pmd';
|
||||
supportedLanguages = ['java'];
|
||||
private pmdDir: string | null = null;
|
||||
private jarPathChecked = false;
|
||||
private auxResolver = new AuxClasspathResolver();
|
||||
|
||||
private resolvePmdDir(): string {
|
||||
@@ -117,7 +116,7 @@ export class PmdAdapter implements LinterAdapter {
|
||||
proc.stdout.on('data', (data: Buffer) => { stdout += data.toString(); });
|
||||
proc.stderr.on('data', (data: Buffer) => { stderr += data.toString(); });
|
||||
proc.on('close', (code) => {
|
||||
if (code === 0 || code === 4 || stdout.length > 0) {
|
||||
if (code === 0 || code === 4) {
|
||||
resolve(stdout);
|
||||
} else {
|
||||
reject(new Error(stderr || `PMD exited with code ${code}`));
|
||||
|
||||
@@ -52,11 +52,19 @@ export function buildPRSMessage(description: string, dialect: string): string {
|
||||
}
|
||||
|
||||
function hasProjectSqlfluffConfig(workspaceRoot: string): boolean {
|
||||
const candidates = ['.sqlfluff', '.sqlfluff.ini'];
|
||||
const candidates: Array<{ file: string; marker: string | null }> = [
|
||||
{ file: '.sqlfluff', marker: null },
|
||||
{ file: 'setup.cfg', marker: '[sqlfluff]' },
|
||||
{ file: 'tox.ini', marker: '[sqlfluff]' },
|
||||
{ file: 'pep8.ini', marker: '[sqlfluff]' },
|
||||
{ file: 'pyproject.toml', marker: '[tool.sqlfluff]' },
|
||||
];
|
||||
for (const candidate of candidates) {
|
||||
if (fs.existsSync(path.join(workspaceRoot, candidate))) {
|
||||
return true;
|
||||
}
|
||||
const filePath = path.join(workspaceRoot, candidate.file);
|
||||
if (!fs.existsSync(filePath)) { continue; }
|
||||
if (candidate.marker === null) { return true; }
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
if (content.includes(candidate.marker)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+16
-7
@@ -12,13 +12,17 @@ let orchestrator: Orchestrator;
|
||||
let markers: DiagnosticMarkers;
|
||||
|
||||
async function runStaticAndApply(document: vscode.TextDocument): Promise<void> {
|
||||
const version = document.version;
|
||||
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '';
|
||||
const workingDir = workspaceRoot || vscode.Uri.joinPath(document.uri, '..').fsPath;
|
||||
const result = await orchestrator.runStaticAnalysis(document, workingDir);
|
||||
const current = vscode.workspace.textDocuments.find(d => d.uri.toString() === document.uri.toString());
|
||||
if (!current || current.version !== version) { return; }
|
||||
markers.apply(document.uri, result.diagnostics);
|
||||
try {
|
||||
const version = document.version;
|
||||
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '';
|
||||
const workingDir = workspaceRoot || vscode.Uri.joinPath(document.uri, '..').fsPath;
|
||||
const result = await orchestrator.runStaticAnalysis(document, workingDir);
|
||||
const current = vscode.workspace.textDocuments.find(d => d.uri.toString() === document.uri.toString());
|
||||
if (!current || current.version !== version) { return; }
|
||||
markers.apply(document.uri, result.diagnostics);
|
||||
} catch (err) {
|
||||
console.error('[code-reviewer] static analysis failed:', err);
|
||||
}
|
||||
}
|
||||
|
||||
const analysisTimers = new Map<string, NodeJS.Timeout>();
|
||||
@@ -113,5 +117,10 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
for (const timer of analysisTimers.values()) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
analysisTimers.clear();
|
||||
markers?.dispose();
|
||||
orchestrator = undefined!;
|
||||
}
|
||||
|
||||
+10
-2
@@ -66,9 +66,17 @@ export function mergeResults(input: MergeInput): MergedReport {
|
||||
d => d.range.start.line
|
||||
);
|
||||
|
||||
const translationsByRule = new Map<string, TranslatedDiagnostic[]>();
|
||||
for (const td of input.translatedDiagnostics) {
|
||||
const list = translationsByRule.get(td.originalRuleId) ?? [];
|
||||
list.push(td);
|
||||
translationsByRule.set(td.originalRuleId, list);
|
||||
}
|
||||
|
||||
const linterDiagnostics = sortBySeverityAndLine(
|
||||
input.staticDiagnostics.map((d, i) => {
|
||||
const td = input.translatedDiagnostics[i];
|
||||
input.staticDiagnostics.map(d => {
|
||||
const list = translationsByRule.get(d.ruleId);
|
||||
const td = list?.shift();
|
||||
if (td) {
|
||||
return { ...d, message: td.translatedMessage, suggestion: td.translatedSuggestion || d.suggestion };
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ export class Orchestrator {
|
||||
private adapters: LinterAdapter[];
|
||||
|
||||
constructor() {
|
||||
// 单语言单 linter 设计:按 linters.<language> 单选配置分派一个适配器;
|
||||
// 需多引擎的文件走组合适配器(如 JspAdapter = PMD + ESLint + Stylelint)。
|
||||
this.adapters = [
|
||||
new ESLintAdapter(),
|
||||
new PmdAdapter(),
|
||||
@@ -27,16 +29,6 @@ export class Orchestrator {
|
||||
];
|
||||
}
|
||||
|
||||
getAdapterMap(): Map<string, LinterAdapter> {
|
||||
const map = new Map<string, LinterAdapter>();
|
||||
for (const adapter of this.adapters) {
|
||||
for (const lang of adapter.supportedLanguages) {
|
||||
map.set(lang, adapter);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
async runStaticAnalysis(
|
||||
document: vscode.TextDocument,
|
||||
workingDir: string
|
||||
@@ -81,8 +73,4 @@ export class Orchestrator {
|
||||
duration: Date.now() - startTime,
|
||||
};
|
||||
}
|
||||
|
||||
getAdaptersByIds(ids: string[]): LinterAdapter[] {
|
||||
return ids.map(id => this.adapters.find(a => a.id === id)).filter(Boolean) as LinterAdapter[];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user