feat: 支持@oak-ignore以跳过警告

This commit is contained in:
Pan Qiancheng 2026-01-04 14:16:03 +08:00
parent 0eaaed513a
commit 9a9066f2f2
3 changed files with 125 additions and 3 deletions

View File

@ -1 +1 @@
export {};
export declare const OAK_IGNORE_TAGS: string[];

View File

@ -1,10 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OAK_IGNORE_TAGS = void 0;
const tslib_1 = require("tslib");
const ts = tslib_1.__importStar(require("typescript"));
const path = tslib_1.__importStar(require("path"));
const fs = tslib_1.__importStar(require("fs"));
const process_1 = require("process");
exports.OAK_IGNORE_TAGS = [
'@oak-ignore',
'@oak-ignore-asynccontext',
];
// ANSI 颜色代码
const colors = {
reset: '\x1b[0m',
@ -102,9 +107,13 @@ function performCustomChecks(program, typeChecker, customConfig) {
if (!isPromiseType(returnType)) {
return;
}
// 检查是否被 await 修饰
// 检查是否被 await 修饰
if (!isAwaited(node)) {
const sourceFile = node.getSourceFile();
// 检查是否有忽略注释
if (hasIgnoreComment(node, sourceFile)) {
return;
}
const methodName = propertyAccess.name.getText(sourceFile);
const objectName = objectExpression.getText(sourceFile);
diagnostics.push({
@ -117,6 +126,51 @@ function performCustomChecks(program, typeChecker, customConfig) {
});
}
}
function hasIgnoreComment(node, sourceFile) {
const fullText = sourceFile.getFullText();
// 检查当前节点及其父节点向上查找最多3层
let currentNode = node;
let depth = 0;
const maxDepth = 5;
while (currentNode && depth < maxDepth) {
// 检查前导注释
const nodeFullStart = currentNode.getFullStart();
const leadingComments = ts.getLeadingCommentRanges(fullText, nodeFullStart);
if (leadingComments && leadingComments.length > 0) {
for (const comment of leadingComments) {
const commentText = fullText.substring(comment.pos, comment.end);
if (isIgnoreComment(commentText)) {
return true;
}
}
}
// 检查尾随注释
const nodeEnd = currentNode.getEnd();
const trailingComments = ts.getTrailingCommentRanges(fullText, nodeEnd);
if (trailingComments && trailingComments.length > 0) {
for (const comment of trailingComments) {
const commentText = fullText.substring(comment.pos, comment.end);
if (isIgnoreComment(commentText)) {
return true;
}
}
}
// 向上查找父节点
currentNode = currentNode.parent;
depth++;
// 如果遇到函数边界,停止查找
if (currentNode && (ts.isFunctionDeclaration(currentNode) ||
ts.isFunctionExpression(currentNode) ||
ts.isArrowFunction(currentNode) ||
ts.isMethodDeclaration(currentNode))) {
break;
}
}
return false;
}
function isIgnoreComment(commentText) {
return exports.OAK_IGNORE_TAGS.some(tag => commentText.includes(tag));
}
function isAsyncContextType(type, modules) {
// 检查类型本身
if (checkTypeSymbol(type, modules)) {

View File

@ -3,6 +3,11 @@ import * as path from 'path';
import * as fs from 'fs';
import { cwd } from 'process';
export const OAK_IGNORE_TAGS = [
'@oak-ignore',
'@oak-ignore-asynccontext',
];
// 定义自定义配置的类型
interface OakBuildChecksConfig {
context?: {
@ -160,9 +165,15 @@ function performCustomChecks(
return;
}
// 检查是否被 await 修饰
// 检查是否被 await 修饰
if (!isAwaited(node)) {
const sourceFile = node.getSourceFile();
// 检查是否有忽略注释
if (hasIgnoreComment(node, sourceFile)) {
return;
}
const methodName = propertyAccess.name.getText(sourceFile);
const objectName = objectExpression.getText(sourceFile);
@ -177,6 +188,63 @@ function performCustomChecks(
}
}
function hasIgnoreComment(node: ts.Node, sourceFile: ts.SourceFile): boolean {
const fullText = sourceFile.getFullText();
// 检查当前节点及其父节点向上查找最多3层
let currentNode: ts.Node | undefined = node;
let depth = 0;
const maxDepth = 5;
while (currentNode && depth < maxDepth) {
// 检查前导注释
const nodeFullStart = currentNode.getFullStart();
const leadingComments = ts.getLeadingCommentRanges(fullText, nodeFullStart);
if (leadingComments && leadingComments.length > 0) {
for (const comment of leadingComments) {
const commentText = fullText.substring(comment.pos, comment.end);
if (isIgnoreComment(commentText)) {
return true;
}
}
}
// 检查尾随注释
const nodeEnd = currentNode.getEnd();
const trailingComments = ts.getTrailingCommentRanges(fullText, nodeEnd);
if (trailingComments && trailingComments.length > 0) {
for (const comment of trailingComments) {
const commentText = fullText.substring(comment.pos, comment.end);
if (isIgnoreComment(commentText)) {
return true;
}
}
}
// 向上查找父节点
currentNode = currentNode.parent;
depth++;
// 如果遇到函数边界,停止查找
if (currentNode && (
ts.isFunctionDeclaration(currentNode) ||
ts.isFunctionExpression(currentNode) ||
ts.isArrowFunction(currentNode) ||
ts.isMethodDeclaration(currentNode)
)) {
break;
}
}
return false;
}
function isIgnoreComment(commentText: string): boolean {
return OAK_IGNORE_TAGS.some(tag => commentText.includes(tag));
}
function isAsyncContextType(type: ts.Type, modules: string[]): boolean {
// 检查类型本身
if (checkTypeSymbol(type, modules)) {