UNPKG

@lcap/builder

Version:
201 lines (200 loc) 8.54 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformFunc2Nasl = exports.transformVariable = exports.transformStatement = exports.transformParam2Nasl = void 0; const utils_1 = require("./utils"); const transform_expression2nasl_1 = __importDefault(require("./transform-expression2nasl")); const transform_tstype2nasl_1 = __importDefault(require("./transform-tstype2nasl")); const getTypeAnnotation = (typeAnnotation) => { if (typeAnnotation && typeAnnotation.type === 'TSTypeAnnotation') { return (0, transform_tstype2nasl_1.default)(typeAnnotation.typeAnnotation); } return null; }; const getRestElementTypeAnnotation = (param, typeNames = []) => { if (!param.typeAnnotation || param.typeAnnotation.type !== 'TSTypeAnnotation') { return null; } if (param.typeAnnotation.typeAnnotation.type === 'TSTypeReference' && ((param.typeAnnotation.typeAnnotation.typeName.type === 'TSQualifiedName' && param.typeAnnotation.typeAnnotation.typeName.right.name === 'List') || (param.typeAnnotation.typeAnnotation.typeName.type === 'Identifier' && param.typeAnnotation.typeAnnotation.typeName.name === 'Array')) && param.typeAnnotation.typeAnnotation.typeParameters && param.typeAnnotation.typeAnnotation.typeParameters.params && param.typeAnnotation.typeAnnotation.typeParameters.params.length > 0) { return (0, transform_tstype2nasl_1.default)(param.typeAnnotation.typeAnnotation.typeParameters.params[0], typeNames); } if (param.typeAnnotation.typeAnnotation.type === 'TSArrayType') { return (0, transform_tstype2nasl_1.default)(param.typeAnnotation.typeAnnotation.elementType, typeNames); } return (0, transform_tstype2nasl_1.default)(param.typeAnnotation.typeAnnotation, typeNames); }; function transformParam2Nasl(paramAST) { switch (paramAST.type) { case 'Identifier': return { concept: 'Param', name: paramAST.name, description: '', typeAnnotation: getTypeAnnotation(paramAST.typeAnnotation), }; case 'RestElement': if (paramAST.argument.type !== 'Identifier') { throw new Error(`解析函数参数失败,不支持该参数类型 ${(0, utils_1.getNodeCode)(paramAST)}`); } return { concept: 'Param', name: paramAST.argument.name, description: '', spread: true, typeAnnotation: getRestElementTypeAnnotation(paramAST), }; case 'AssignmentPattern': if (paramAST.left.type !== 'Identifier') { throw new Error(`解析函数参数失败,不支持该参数类型 ${(0, utils_1.getNodeCode)(paramAST)}`); } return { concept: 'Param', name: paramAST.left.name, description: '', typeAnnotation: getTypeAnnotation(paramAST.left.typeAnnotation), defaultValue: { concept: 'DefaultValue', expression: (0, transform_expression2nasl_1.default)(paramAST.right), playground: [], }, }; default: throw new Error(`解析函数参数失败,不支持该参数类型 ${(0, utils_1.getNodeCode)(paramAST)}`); } } exports.transformParam2Nasl = transformParam2Nasl; function transformStatement(statement) { if (statement.type === 'BlockStatement') { return statement.body.map(transformStatement); } if (statement.type === 'IfStatement') { return { concept: 'IfStatement', test: (0, transform_expression2nasl_1.default)(statement.test), consequent: (0, utils_1.normalizeArray)(transformStatement(statement.consequent)), alternate: statement.alternate ? (0, utils_1.normalizeArray)(transformStatement(statement.alternate)) : [], }; } if (statement.type === 'SwitchStatement' && statement.discriminant) { const testLeft = (0, transform_expression2nasl_1.default)(statement.discriminant); return { concept: 'SwitchStatement', cases: statement.cases.map((switchCaseAST) => ({ concept: 'SwitchCase', test: { concept: 'BinaryExpression', left: testLeft, right: switchCaseAST.test ? (0, transform_expression2nasl_1.default)(switchCaseAST.test) : null, operator: '==', }, consequent: switchCaseAST.consequent.map((st) => transformStatement(st)).flat(), })), }; } if (statement.type === 'ForInStatement') { if (statement.left.type !== 'VariableDeclaration') { throw new Error('解析 for in 语句失败, 左侧仅允许定义变量,例如 var xxx in list'); } return { concept: 'ForEachStatement', each: (0, transform_expression2nasl_1.default)(statement.right), item: { concept: 'Param', name: statement.left.declarations[0].id && statement.left.declarations[0].id.type === 'Identifier' ? statement.left.declarations[0].id.name : 'item', description: '', }, index: { concept: 'Param', name: statement.left.declarations[1] && statement.left.declarations[1].id && statement.left.declarations[1].id.type === 'Identifier' ? statement.left.declarations[1].id.name : 'index', description: '', }, start: { concept: 'NumericLiteral', value: 0, }, body: (0, utils_1.normalizeArray)(transformStatement(statement.body)), }; } if (statement.type === 'WhileStatement') { return { concept: 'WhileStatement', test: (0, transform_expression2nasl_1.default)(statement.test), body: (0, utils_1.normalizeArray)(transformStatement(statement.body)), }; } if (statement.type === 'ExpressionStatement') { return (0, transform_expression2nasl_1.default)(statement.expression); } if (statement.type === 'ReturnStatement') { return { concept: 'End', }; } throw new Error(`解析语句失败, Nasl 不支持该语法, ${(0, utils_1.getNodeCode)(statement)}`); } exports.transformStatement = transformStatement; function transformVariable(ast) { if (ast.id.type !== 'Identifier') { throw new Error(`解析变量定义失败, ${(0, utils_1.getNodeCode)(ast)}`); } const variable = { concept: 'Variable', name: ast.id.name, description: '', }; if (ast.id.typeAnnotation && ast.id.typeAnnotation.type === 'TSTypeAnnotation') { variable.typeAnnotation = (0, transform_tstype2nasl_1.default)(ast.id.typeAnnotation.typeAnnotation); } if (ast.init) { variable.defaultValue = (0, transform_expression2nasl_1.default)(ast.init); } return variable; } exports.transformVariable = transformVariable; function transformFunc2Nasl(funcAst) { if (!funcAst.id) { throw new Error('解析函数失败,未定义函数名称'); } const variables = []; const statements = funcAst.body.body.filter((s) => { if (s.type !== 'VariableDeclaration') { return true; } s.declarations.forEach((decla) => { if (decla.id && decla.id.type === 'Identifier') { variables.push(transformVariable(decla)); } }); return false; }); const Logic = { concept: 'Logic', name: funcAst.id.name, variables, params: funcAst.params.map(transformParam2Nasl), returns: [], playground: [], body: [ { concept: 'Start', }, ...statements.map(transformStatement), ], }; if (Logic.body[Logic.body.length - 1].concept !== 'End') { Logic.body.push({ concept: 'End', }); } return Logic; } exports.transformFunc2Nasl = transformFunc2Nasl; exports.default = transformFunc2Nasl;