@lcap/nasl
Version:
NetEase Application Specific Language
212 lines • 8.65 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformTSCodeToExpression = exports.transformTSCodeEx = exports.parseNaturalTSLogic = exports.tryTransformTSCode = exports.transformTSCode = void 0;
/* eslint-disable global-require */
/* eslint-disable @typescript-eslint/no-use-before-define */
const babel = __importStar(require("@babel/core"));
const tools_1 = require("./tools");
const utils_1 = require("./transforms/utils");
const transform2LogicItem_1 = require("./transforms/transform2LogicItem");
const transform2TypeAnnotation_1 = require("./transforms/transform2TypeAnnotation");
function getLogicTypeFromName(logicName) {
if (logicName.includes('on_') || logicName.includes('businessLogic_'))
return 'event_logic';
if (logicName.includes('viewLogic_'))
return 'view_logic';
return 'global_logic';
}
function transformTSCode2Logic(body, root, contextLogicName, logicNames, needThrowError) {
const logic = new utils_1.naslTypes.Logic();
logic.body = [
new utils_1.naslTypes.Start(),
];
let parameters = [];
let statements = [];
let func;
const exportLogic = body?.type === 'ExportNamedDeclaration';
let currentLogicName = '';
if (exportLogic) {
func = body?.declaration;
currentLogicName = func?.id?.name;
}
else {
func = body;
currentLogicName = body?.id?.name;
}
logic.name = currentLogicName;
parameters = func.params;
statements = [...func.body?.directives, ...func.body.body];
const currentPositionComment = root?.comments?.find((comment) => comment.type === 'CommentLine' && comment.value === ' 当前位置');
if (currentPositionComment) {
statements = statements.filter((stat) => stat.start > currentPositionComment.start);
}
statements = statements.filter((node) => node?.type !== 'EmptyStatement');
const newStatements = [];
statements.forEach((node, index) => {
if (node?.leadingComments?.length) {
newStatements.push(...node?.leadingComments);
}
if (node?.trailingComments?.length && index === statements.length - 1) {
newStatements.push(...node?.trailingComments);
}
newStatements.push(node);
});
statements = newStatements;
parameters.forEach((node) => {
const param = (0, transform2LogicItem_1.transform2Param)(node, { $$beacon: true, transformType: 'attr' }) || undefined;
param && logic.params.push(param);
});
statements.forEach((node) => {
const item = (0, transform2LogicItem_1.transform2LogicItem)(node, {
$$beacon: true,
transformType: 'logic',
logic,
logicType: getLogicTypeFromName(contextLogicName),
logicNames,
needThrowError
});
item && logic.body.push(item);
});
if (!exportLogic && logicNames?.length > 1) {
logic.body.push(new utils_1.naslTypes.End());
}
const lastItem = logic.body[logic.body.length - 1];
if (lastItem && lastItem.concept !== 'End') {
logic.body.push(new utils_1.naslTypes.End());
}
if (logic.returns[0]?.name) {
const index = logic.variables.findIndex((variable) => variable.name === logic.returns[0].name);
if (index >= 0)
logic.variables.splice(index, 1);
if (func.returnType && !logic.returns[0].typeAnnotation) {
const typeAnnotation = (0, transform2TypeAnnotation_1.transform2TypeAnnotation)(func.returnType?.typeAnnotation, { $$beacon: true });
if (typeAnnotation)
logic.returns[0].typeAnnotation = typeAnnotation;
}
}
return logic;
}
function checkFormat(tsCode) {
if (!/\}\s*$/.test(tsCode)) {
(0, utils_1.throwError)(undefined, '格式不正确');
}
}
function transformTSCode(tsCode, contextLogicName, unNeedUID, needThrowError) {
checkFormat(tsCode);
if (!contextLogicName) {
const functionRE = /function\s+(\w+)\s*\(/;
const cap = tsCode.match(functionRE);
if (cap) {
contextLogicName = cap[1];
}
else {
(0, utils_1.throwError)(undefined, '无法解析函数名');
}
}
const root = babel.parseSync(tsCode, {
filename: 'result.ts',
presets: [require('@babel/preset-typescript')],
});
let needHandleFuncs = root?.program?.body || [];
let logics;
if (needHandleFuncs?.length > 1) {
// 获取多个逻辑的name
const logicNames = needHandleFuncs.map((item) => item?.id?.name || item?.declaration?.id?.name);
logics = needHandleFuncs.map((item) => transformTSCode2Logic(item, root, contextLogicName, logicNames, needThrowError));
}
else {
logics = transformTSCode2Logic(needHandleFuncs[0], root, contextLogicName, [], needThrowError);
}
if (!unNeedUID) {
const { node: newLogic } = (0, tools_1.genAIUID)(logics, 'nl2logic');
return newLogic;
}
else {
return logics;
}
}
exports.transformTSCode = transformTSCode;
function tryTransformTSCode(tsCode, contextLogicName, unNeedUID, needThrowError) {
if (tsCode.includes('```')) {
const cap = tsCode.match(/```.*\n([\s\S]+?)```/);
if (cap)
tsCode = cap[1].trim();
}
return transformTSCode(tsCode, contextLogicName, unNeedUID, needThrowError);
}
exports.tryTransformTSCode = tryTransformTSCode;
function parseNaturalTSLogic(tsCode) {
return transformTSCode(tsCode, undefined, true);
}
exports.parseNaturalTSLogic = parseNaturalTSLogic;
function transformTSCodeEx(answer, activeLogic, context) {
let logicName = activeLogic.name;
const { app, nasl } = context;
if (activeLogic.parentNode instanceof nasl.BindEvent && activeLogic.parentNode.parentNode instanceof nasl.View) {
logicName = `viewLogic_${activeLogic.name}`;
}
else if (activeLogic.parentNode instanceof nasl.BindEvent && activeLogic.parentNode.parentNode instanceof nasl.ViewElement) {
logicName = `on_${(activeLogic.parentNode).element.name}_${activeLogic.name}`;
}
else if (activeLogic?.concept === 'BusinessLogic') {
logicName = `businessLogic_${activeLogic?.name}`;
}
else {
logicName = activeLogic.name;
}
const logic = tryTransformTSCode(answer, logicName);
app.emit('collect:start', { actionMsg: '自然语言生成代码' });
logic.params.forEach((param) => {
if (!activeLogic.params.find((_) => _.name === param.name))
activeLogic.addParam(param.toJSON());
});
logic.variables.forEach((variable) => {
if (!activeLogic.variables.find((_) => _.name === variable.name))
activeLogic.addVariable(variable.toJSON());
});
if (logic.returns.length && !activeLogic.returns.length) {
activeLogic.addReturn(logic.returns[0].toJSON());
}
logic.body.forEach((item) => activeLogic.insertItemInBodyAt(item.toJSON(), activeLogic.body.length - 1));
app.emit('collect:end');
}
exports.transformTSCodeEx = transformTSCodeEx;
function transformTSCodeToExpression(answer, context) {
let logic;
try {
logic = tryTransformTSCode(answer, '');
}
catch (error) {
throw new Error(error);
}
const { app } = context;
app.emit('collect:start', { actionMsg: '自然语言生成代码' });
const { body } = logic;
app.emit('collect:end');
return body;
}
exports.transformTSCodeToExpression = transformTSCodeToExpression;
//# sourceMappingURL=transformTSCode.js.map