# Code Reviewer — VSCode Extension Design Spec ## 1. 概述 VSCode 代码审查与规范检查一体化工具。集成多语言静态分析器与 AI 智能审查,为开发团队提供代码质量保障。 ### 核心能力 - 多语言代码静态分析(ESLint、PMD、Stylelint、sql-lint 等) - AI 辅助深度审查与问题解释/翻译 - 自定义规则检查(YAML 定义 + AI 语义评估) - 自动修复建议与批量修复(快照撤销) - Webview 审查报告面板 --- ## 2. 架构总览 插件分为四层: ``` UI 层 — Webview 审查面板 / Inline Diagnostic / Code Action 核心层 — Orchestrator(编排器)+ AI 审查引擎 适配层 — Linter 适配器(统一 LinterAdapter 接口) 基础层 — 配置管理 / 规则管理 / 报告导出 ``` 所有 linter 统一实现 `LinterAdapter` 接口,通过 Orchestrator 调度,结果聚合后通过 Webview 面板展示。 --- ## 3. 适配器层 ### 3.1 设计决策 | 决策项 | 结论 | 说明 | |--------|------|------| | 支持语言 | Java / JS/TS / CSS / SQL / JSP | 不支持 Python、Go | | 注册方式 | 硬编码(方案 A) | 适配器数量少,无需过度设计 | | 审查粒度 | 单文件 | `check()` 接收单个 `TextDocument` | | 目标平台 | Windows | PMD classpath 分隔符使用 `;` | ### 3.2 统一接口 ```typescript interface LinterDiagnostic { severity: 'error' | 'warning' | 'info'; ruleId: string; // 格式: "linter名:规则ID" message: string; range: vscode.Range; suggestion?: string; } interface AdapterResult { diagnostics: LinterDiagnostic[]; status: 'ok' | 'tool-unavailable' | 'execution-failed'; errorMessage?: string; } interface LinterAdapter { id: string; supportedLanguages: string[]; check(document: vscode.TextDocument, workingDir: string): Promise; isAvailable(): boolean; } ``` **错误状态说明**: | 状态 | 含义 | 用户感知 | |------|------|---------| | `ok` | 检查成功 | 正常显示结果 | | `tool-unavailable` | 工具未安装/未找到 | 提示用户安装对应工具 | | `execution-failed` | 工具已安装但执行出错 | 显示错误信息,引导排查 | ### 3.3 适配器清单 | 适配器 | 语言 | 实现方式 | 特殊处理 | |--------|------|----------|----------| | ESLint | JS/TS | eslint npm 包 `lintText()` | 直接接收代码文本,支持虚拟文档 | | PMD | Java | Java 子进程调用 | 支持 stdin 传入代码,支持虚拟文档 | | Stylelint | CSS | stylelint npm 包 `lint({ code })` | 直接接收代码文本,支持虚拟文档 | | sql-lint | SQL | sqlfluff CLI 调用 | 支持 SQL 和 PL/SQL,方言映射 | | JSP | JSP | 组合适配器(PMD + ESLint + Stylelint) | 提取内嵌代码块后分发检查 | ### 3.4 PMD 适配器特殊设计 PMD 是 Java 工具,需要特殊处理: 1. **JAR 文件管理**:插件自带 `jars/pmd/` 目录存放 PMD 依赖 2. **规则集配置**:支持自定义规则集 XML 文件 3. **Java 包装器**:`PmdRunner.java` 简化调用,输出 JSON 格式 4. **虚拟文档支持**:通过 stdin 传入代码,无需真实文件 **PmdRunner.java 核心逻辑**(`jars/pmd/PmdRunner.java`): ``` 参数: filePath (传 "-" 表示从 stdin 读取), ruleset → 构建 PMDConfiguration → 配置 JSON 渲染器 → 若 filePath 为 "-",从 stdin 读代码 → 写入临时文件 → 执行 PMD 分析 → 输出 JSON 到 stdout → 清理临时文件 ``` **PmdAdapter.check() 虚拟文档处理**: ``` if 虚拟文档 (uri.scheme === 'untitled') → java -cp "classpath;dist" PmdRunner "-" ruleset → stdin 传入 document.getText() else → java -cp "classpath;dist" PmdRunner document.fileName ruleset ``` ### 3.5 JSP 适配器设计 JSP 适配器是**组合适配器**,自身不做检查,而是将 JSP 文件拆分后交给其他适配器: ``` JSP 文件输入 │ ├─ 1. 调用 PMD 检查 JSP 规范 │ → 使用 pmd-jsp-ruleset.xml │ └─ 2. jsp-extractor 提取内嵌代码块 ├─