@lcap/nasl
Version:
NetEase Application Specific Language
86 lines • 3.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ruleConvertIncompatibleAssignmentToUnion = void 0;
const nasl_1 = require("@lcap/nasl");
const asserts_1 = require("@lcap/nasl-concepts/asserts");
const regex = /赋值:类型不一致!右边类型:(.*),左边类型:(.*)。/;
function isRelatedToAStructure(x) {
if (!x) {
return false;
}
if (x.typeKind === 'anonymousStructure') {
return true;
}
else if (x.typeKind === 'union') {
// 不递归看了,只看一层
return x.typeArguments?.some((x) => x?.typeKind === 'anonymousStructure');
}
}
function resolveAssignmentTarget(node) {
const assignment = (0, asserts_1.isAssignment)(node) ? node : node.getAncestor('Assignment');
if ((0, asserts_1.isAssignment)(assignment) && assignment.left && assignment.right) {
for (const ctx of [node.getAncestor('SubLogic'), node.getAncestor('Logic')]) {
if (!ctx) {
continue;
}
if ((0, asserts_1.isLogic)(node) && node.concept !== 'Logic') {
continue;
}
const lhsAnnotation = assignment.left.typeAnnotation ?? assignment.left.__TypeAnnotation;
const rhsAnnotation = assignment.right.typeAnnotation ?? assignment.right.__TypeAnnotation;
const hasError = [lhsAnnotation, rhsAnnotation].some((x) => x?.isRelatedToErrorType());
if (ctx && lhsAnnotation && rhsAnnotation && hasError) {
const target = ctx.returns.find((x) => x.name === assignment.left.name) ??
ctx.variables.find((x) => x.name === assignment.left.name) ??
ctx.params.find((x) => x.name === assignment.left.name);
if (target) {
if ((0, asserts_1.isParam)(target)) {
// 解析为Param,不支持修改,直接返回
return null;
}
return {
target,
lhsAnnotation,
rhsAnnotation,
};
}
}
}
}
return null;
}
exports.ruleConvertIncompatibleAssignmentToUnion = {
title: '自动修复不兼容的赋值为联合类型',
disableForBatch: true,
isFixable: (diagnostic) => {
const res = diagnostic.message?.match(regex);
const ty1 = res?.[1];
const ty2 = res?.[2];
if (ty1 && ty2) {
// @ts-expect-error BaseNode 类型无法匹配
const res = resolveAssignmentTarget(diagnostic.node);
if (res) {
const { lhsAnnotation, rhsAnnotation } = res;
const newTy = nasl_1.TypeAnnotation.createUnion(lhsAnnotation, rhsAnnotation);
if (isRelatedToAStructure(newTy)) {
// 结果类型中有匿名数据结构就不提供自动修复
return false;
}
return { hint: `一键设置为 “${newTy.toUI()}” 类型` };
}
}
return false;
},
commitFix: (node) => {
if (!node) {
return;
}
const resolved = resolveAssignmentTarget(node);
if (resolved) {
const { target, lhsAnnotation, rhsAnnotation } = resolved;
const resultTypeAnnotation = nasl_1.TypeAnnotation.createUnion(lhsAnnotation, rhsAnnotation);
target.update({ typeAnnotation: resultTypeAnnotation });
}
},
};
//# sourceMappingURL=rule-convert-incompatible-assignment-to-union.js.map