# Step 12 — Phase 4.4: 结果合并 **依赖**: Step 08, 10, 11 **参考设计**: §14.1 ## 目标 将适配器诊断、AI 翻译诊断、自定义规则结果、AI 深度审查结果合并为一个 `MergedReport`。 ## 新建文件 | # | 文件 | 说明 | |---|------|------| | 1 | `src/merger/merger.ts` | `mergeResults()` → `MergedReport` | --- ## `src/merger/merger.ts` ```typescript import { LinterDiagnostic, Severity } from '../types'; import { TranslatedDiagnostic, CustomRuleResult, AIFinding } from '../ai/schema'; export interface MergedReport { linterDiagnostics: LinterDiagnostic[]; customRuleDiagnostics: LinterDiagnostic[]; translatedDiagnostics: TranslatedDiagnostic[]; aiFindings: AIFinding[]; linterCount: number; customRuleCount: number; aiCount: number; errors: string[]; degraded: boolean; duration: number; filePath: string; language: string; adapterNames: string[]; fixableLinterIndices: number[]; fixableCustomIndices: number[]; } interface MergeInput { staticDiagnostics: LinterDiagnostic[]; customRuleResults: CustomRuleResult[]; translatedDiagnostics: TranslatedDiagnostic[]; aiFindings: AIFinding[]; errors: string[]; degraded: boolean; startTime: number; filePath: string; language: string; adapterIds: string[]; } export function mergeResults(input: MergeInput): MergedReport { const customRuleDiagnostics: LinterDiagnostic[] = input.customRuleResults.map(r => ({ severity: r.severity as Severity, ruleId: r.ruleId, message: r.message, range: new (require('vscode').Range)(Math.max(0, r.line - 1), 0, Math.max(0, r.line - 1), 1), })); const linterCount = input.staticDiagnostics.length; const customRuleCount = customRuleDiagnostics.length; const aiCount = input.aiFindings.length; const fixableLinterIndices = input.staticDiagnostics .map((_, i) => i) .filter(i => input.staticDiagnostics[i].suggestion); const fixableCustomIndices = customRuleDiagnostics .map((_, i) => i); return { linterDiagnostics: input.staticDiagnostics, customRuleDiagnostics, translatedDiagnostics: input.translatedDiagnostics, aiFindings: input.aiFindings, linterCount, customRuleCount, aiCount, errors: input.errors, degraded: input.degraded, duration: Date.now() - input.startTime, filePath: input.filePath, language: input.language, adapterNames: input.adapterIds, fixableLinterIndices, fixableCustomIndices, }; } ``` > **注意**: `require('vscode')` 在合并器中创建 Range。如果遇到问题,可使用 `import * as vscode from 'vscode'` 替代,或在调用处传入 `vscode` 模块。 --- ## 关键逻辑 - `customRuleResults` → `customRuleDiagnostics`(LinterDiagnostic 格式,范围设为首字符) - 统计计数器:linterCount / customRuleCount / aiCount(面板 Tab 计数用) - `fixableLinterIndices`: 有 suggestion 的 linter 诊断索引 - `fixableCustomIndices`: 所有自定义规则诊断索引(均可尝试 AI 修复) - duration: 从 startTime 到调用时刻的耗时 --- ## 验收 - [ ] 文件创建完成 - [ ] `npm run compile` 通过 - [ ] `npm run lint` 通过