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