# 打开文件自动静态分析 + 波浪线 设计文档 > 面向 AI 编码 agent 的技术实施文档。本文档包含完整的根因分析、方案设计、文件清单和验收标准,可直接据此编码。 ## 功能目标 修复插件对**已打开文件不做静态分析、不显示波浪线**的问题: 1. VSCode 启动后(`onStartupFinished`)插件自动激活,对**所有已打开的文件**串行做静态分析并显示波浪线。 2. 文本编辑时先清除波浪线(即时反馈),停止输入 1s 后自动重新分析。 3. 保存文件仍按现有 500ms 防抖重分析。 ## 根因分析 | 问题 | 位置 | 说明 | |------|------|------| | 插件不自动激活 | `package.json:12` `activationEvents: []` | 无 `onStartupFinished` 等事件,插件只在执行命令/打开面板时激活 | | 存量文件不分析 | `extension.ts` activate 无初始扫描 | `onDidOpenTextDocument` 只对"激活后新打开"的文件触发,激活前已打开的文件永远不会被分析 | | 编辑不重分析 | `extension.ts:63-66` | `onDidChangeTextDocument` 只 `markers.clear`,需等保存才有波浪线 | ## 架构决策 | 决策 | 选择 | 理由 | |------|------|------| | 激活时机 | `onStartupFinished` | VSCode 启动完成后激活,不拖慢启动,兼容性最好 | | 初始分析范围 | 所有已打开 file 文档 | 行为统一,符合"已打开文件都应有波浪线"预期 | | 批量执行方式 | 串行执行 | 避免多个 JVM(PMD)/ Python 进程(SQLFluff)并发;JS/TS/CSS 为进程内执行,无压力 | | 串行顺序 | 活动文件优先 | 用户眼前文件先出波浪线 | | 编辑时行为 | 1s 防抖自动重分析 | 更接近 ESLint 等 linter 体验 | | 防抖调度 | 统一按 URI 调度器 | 合并保存/编辑两类防抖,逻辑单一 | ## 文件变更清单 | 文件 | 变更 | |------|------| | `package.json` | `activationEvents` 由 `[]` 改为 `["onStartupFinished"]` | | `src/extension.ts` | ① 初始串行扫描(活动文件优先);② 统一 `scheduleAnalysis` 调度器;③ 编辑时防抖重分析 | 无新增依赖。 ## 关键实现 ### 统一防抖调度器(`src/extension.ts`) ```ts const analysisTimers = new Map(); function scheduleAnalysis(document: vscode.TextDocument, delay: number): void { if (document.uri.scheme !== 'file' || !isMarkersEnabled()) { return; } const key = document.uri.toString(); const existing = analysisTimers.get(key); if (existing) { clearTimeout(existing); } const timer = setTimeout(async () => { analysisTimers.delete(key); await runStaticAndApply(document); }, delay); analysisTimers.set(key, timer); } ``` ### 激活时初始串行扫描(活动文件优先) ```ts const docs = vscode.workspace.textDocuments; const active = vscode.window.activeTextEditor?.document; const ordered = [...docs].sort((a, b) => a === active ? -1 : b === active ? 1 : 0); for (const doc of ordered) { if (doc.uri.scheme !== 'file' || !isMarkersEnabled()) { continue; } await runStaticAndApply(doc); } ``` ### 事件改写 - `onDidChangeTextDocument`:`markers.clear(uri)` + `scheduleAnalysis(doc, 1000)` - `onDidSaveTextDocument`:删除原 `debounceTimers` Map,改用 `scheduleAnalysis(doc, 500)` 复用现有 `runStaticAndApply`(含版本竞态保护)与 `markers.apply`,行为不变。 ## 影响范围 - **激活行为**:插件随 VSCode 启动自动激活(内存常驻,激活逻辑本已完整,代价极小) - **兼容性**:`markers.enabled` 配置全程生效;命令/CodeLens/AI 审查流程不受影响 - **进程压力**:初始串行扫描保证任一时刻最多 1 个 JVM 在跑 ## 验收标准 1. 启动 Extension Dev Host,预置多个已打开文件(含活动与非活动),确认启动后活动文件波浪线先出现、其余依次出现 2. 编辑文件停止 1s 后波浪线自动刷新;输入过程中波浪线消失 3. 保存文件 500ms 后波浪线刷新 4. `markers.enabled=false` 时不显示任何波浪线且不触发分析 5. `npm run lint`、`npm run compile` 通过