Files
2026Technology-Competition/src/orchestrator/orchestrator.ts
T
范智鹏 3d8119d9c9 feat: 自动修复重构与审查面板交互修复 + 静态分析 AI 翻译配对 + SQLFluff 方言显示
- 自动修复:废弃 AI 修复,改 linter 原生 fix 多轮收敛;CodeAction hover + 面板修复/全部修复 + 快照 diff 撤销;hover 修复不入「已修复」列表、重新审查清空;修复/撤销后自动保存;单条修复只修目标问题(区间重叠收敛,不再连带相邻同规则)
- 审查面板:内联 JS 外部化(reviewPanel.js)修复 CSP 屏蔽导致的修复按钮/行号跳转/tab 失效;面板操作不依赖文件焦点(resolveFixDocument);行号跳转定位已打开编辑器,不在面板列新开副本
- 静态分析:translatedDiagnostics 规则 ID 归一化配对 + 深度审查 prompt 强化,静态分析条目显示中文翻译与逐条 AI 建议
- 波浪线:诊断补 source/code,hover 显示快速修复链接
- SQLFluff:设置面板方言徽章(显式/全局/项目/内置来源配色)
2026-08-18 21:41:51 +08:00

106 lines
2.9 KiB
TypeScript

import * as vscode from 'vscode';
import type { LinterAdapter, LinterDiagnostic } from '../types';
import { getLinterForLanguage, isAdapterEnabled } from '../config';
import { ESLintAdapter } from '../adapters/eslint';
import { PmdAdapter } from '../adapters/pmd';
import { StylelintAdapter } from '../adapters/stylelint';
import { SqlFluffAdapter } from '../adapters/sqlfluff';
import { JspAdapter } from '../adapters/jsp';
export interface StaticAnalysisResult {
diagnostics: LinterDiagnostic[];
errors: string[];
adapterIds: string[];
duration: number;
}
export interface CachedAnalysis {
diagnostics: LinterDiagnostic[];
adapterId: string;
workingDir: string;
}
export class Orchestrator {
private adapters: LinterAdapter[];
private analysisCache = new Map<string, CachedAnalysis>();
constructor() {
// 单语言单 linter 设计:按 linters.<language> 单选配置分派一个适配器;
// 需多引擎的文件走组合适配器(如 JspAdapter = PMD + ESLint + Stylelint)。
this.adapters = [
new ESLintAdapter(),
new PmdAdapter(),
new StylelintAdapter(),
new SqlFluffAdapter(),
new JspAdapter(),
];
}
async runStaticAnalysis(
document: vscode.TextDocument,
workingDir: string
): Promise<StaticAnalysisResult> {
const startTime = Date.now();
const languageId = document.languageId;
const selectedLinter = getLinterForLanguage(languageId);
if (!selectedLinter) {
return { diagnostics: [], errors: [], adapterIds: [], duration: 0 };
}
const adapter = this.adapters.find(a => a.id === selectedLinter);
if (!adapter) {
return {
diagnostics: [],
errors: [`未找到适配器: ${selectedLinter}`],
adapterIds: [],
duration: Date.now() - startTime,
};
}
if (!isAdapterEnabled(adapter.id)) {
return {
diagnostics: [],
errors: [],
adapterIds: [],
duration: Date.now() - startTime,
};
}
const result = await adapter.check(document, workingDir);
const errors: string[] = [];
if (result.status !== 'ok') {
errors.push(`[${adapter.id}] ${result.errorMessage ?? result.status}`);
}
this.analysisCache.set(document.uri.toString(), {
diagnostics: result.diagnostics,
adapterId: adapter.id,
workingDir,
});
return {
diagnostics: result.diagnostics,
errors,
adapterIds: [adapter.id],
duration: Date.now() - startTime,
};
}
setAnalysisResult(uri: vscode.Uri, result: CachedAnalysis): void {
this.analysisCache.set(uri.toString(), result);
}
getAnalysisResult(uri: vscode.Uri): CachedAnalysis | undefined {
return this.analysisCache.get(uri.toString());
}
clearAnalysisResult(uri: vscode.Uri): void {
this.analysisCache.delete(uri.toString());
}
getAdapter(adapterId: string): LinterAdapter | undefined {
return this.adapters.find(a => a.id === adapterId);
}
}