ts-oak-plugin/lib/core/asyncContextChecker.js

101 lines
3.2 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncContextChecker = void 0;
class AsyncContextChecker {
constructor(pwd, config, program, typeChecker, tsLib) {
this.pwd = pwd;
this.config = config;
this.program = program;
this.typeChecker = typeChecker;
this.tsLib = tsLib;
// 全局状态(跨文件)
this.functionsWithContextCalls = new Set();
this.functionDeclarations = new Map();
this.functionCallGraph = new Map();
this.directContextCalls = new Map();
// 缓存
this.ignoreCommentNodes = new Map();
this.isInitialized = false;
}
/**
* 初始化:构建全局调用图
*/
initialize() {
if (this.isInitialized)
return;
// 遍历所有文件,构建调用图
for (const sourceFile of this.program.getSourceFiles()) {
if (sourceFile.isDeclarationFile)
continue;
if (!this.isFileInCheckScope(sourceFile.fileName))
continue;
this.preprocessIgnoreComments(sourceFile);
this.collectCallGraph(sourceFile);
}
// 过滤非 Promise 返回的调用
this.filterAsyncContextCalls();
// 传播标记
this.propagateContextMarks();
this.isInitialized = true;
}
/**
* 检查单个文件
*/
checkFile(sourceFile) {
// 确保已初始化
this.initialize();
if (!this.isFileInCheckScope(sourceFile.fileName)) {
return [];
}
const diagnostics = [];
// 检查直接的 context 调用
diagnostics.push(...this.checkDirectContextCalls(sourceFile));
// 检查间接调用
diagnostics.push(...this.checkIndirectCalls(sourceFile));
return diagnostics;
}
isFileInCheckScope(fileName) {
// 复用原有的 isFileInCheckScope 逻辑
// ...
return true; // 简化示例
}
preprocessIgnoreComments(sourceFile) {
// 复用原有的 preprocessIgnoreComments 逻辑
// 将结果存储在 this.ignoreCommentNodes 中
}
collectCallGraph(sourceFile) {
// 复用原有的 collectAndCheck 逻辑
// 收集函数声明和调用关系
}
filterAsyncContextCalls() {
// 复用原有逻辑
}
propagateContextMarks() {
// 复用原有逻辑
}
checkDirectContextCalls(sourceFile) {
// 复用原有逻辑,但只检查当前文件
const diagnostics = [];
// ...
return diagnostics;
}
checkIndirectCalls(sourceFile) {
// 复用原有逻辑,但只检查当前文件
const diagnostics = [];
// ...
return diagnostics;
}
/**
* 清除缓存(当文件变化时)
*/
clearCache() {
this.isInitialized = false;
this.functionsWithContextCalls.clear();
this.functionDeclarations.clear();
this.functionCallGraph.clear();
this.directContextCalls.clear();
this.ignoreCommentNodes.clear();
}
}
exports.AsyncContextChecker = AsyncContextChecker;
//# sourceMappingURL=asyncContextChecker.js.map