UNPKG

@lcap/nasl-parser

Version:

Take Nasl text to Nasl AST with the help of generalized parsing.

388 lines 17 kB
"use strict"; 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.toNaslPrefix = exports.toNaslTyParam = exports.toNaslLogicParam = exports.toNaslLamParam = exports.toNaslLambda = exports.toNaslSubLogic = exports.toNaslDefaultValue = exports.toNaslValArgList = exports.toNaslValArg = exports.toNaslCallLogic = exports.toNaslSQLFilterSuffix = exports.toNaslMemberAccessSuffix = exports.toNaslArrayAccessSuffix = exports.toNaslCallSuffix = exports.BuildBinary = exports.toNaslBinaryExpr = exports.toNaslCallQueryComponent = exports.toNaslAnonymousFunc = exports.toNaslEmptyBrackets = exports.toNaslEnumIntRef = exports.toNaslMapLit = exports.toNaslArrayLit = exports.toNaslUnparsed = exports.toNaslStringInterpolation = exports.toNaslStringLit = exports.toNaslBooleanLit = exports.toNaslNullLit = exports.toNaslDecimalLit = exports.toNaslIntegerLit = exports.toNaslIdentifier = exports.toNaslPostfix = void 0; exports.dispatchToNaslExpr = dispatchToNaslExpr; const to_nasl_type_1 = require("./to-nasl-type"); // toNaslPat, toNaslStatement, const to_nasl_statement_1 = require("./to-nasl-statement"); const common_util_1 = require("./common-util"); const nasl = __importStar(require("./decorated-nasl-ast")); const console_1 = require("console"); const asserts_1 = require("@lcap/nasl-concepts/asserts"); // import { toNaslCallQueryComponentImpl } from './to-nasl-call-query'; let toNaslCallQueryComponentImpl = undefined; const binaryOpToName = new Map([ ['+', 'Add'], ['-', 'Sub'], ['*', 'Mul'], ['/', 'Div'], ['%', 'Mod'], // ['^', 'Pow'], ['&&', 'And'], ['||', 'Or'], ['==', 'Eq'], ['!=', 'Ne'], ['>', 'Gt'], ['<', 'Lt'], ['>=', 'Ge'], ['<=', 'Le'], ['in', 'In'], ['not in', 'NotIn'], ['is', 'Is'], ['is not', 'IsNot'], ]); const toNaslPostfix = ([expr, sfx]) => { // please refactor the four if to switch switch (sfx.cst.__type) { case 'CallSuffix': return (0, exports.toNaslCallLogic)(expr, sfx); case 'ArrayAccessSuffix': return toNaslArrayAccess(expr, sfx); case 'MemberAccessSuffix': return toNaslMemberAccess(expr, sfx); case 'SQLFilterSuffix': return toNaslSQLFilter(expr); default: throw new console_1.error('panic: should not reach here in postfixToNasl1'); } }; exports.toNaslPostfix = toNaslPostfix; function dispatchToNaslExpr(e) { // if (isUnaryExpr(e)) { // let expr : nasl.LogicItem; // if (isPostfixable(e.expr)) { // if (!isEmpty(e.suffix)) { // let res = postfixToNasl1(e.expr, e.suffix.pop()) // e.suffix.forEach(sfx => { // // @ts-ignore // res = postfixToNasl2(res, sfx) // }) // expr = res; // } else { // expr = toNaslExpr(e.expr); // } // e.prefix.forEach(pfx => { // expr = new nasl.UnaryExpression({ // operator: '!', // argument: expr // }) // }); // return expr; // } else { // return toNaslExpr(e.expr); // } // } // if (isBinaryExpression(e)) { // return toNaslBinaryExpr(e); // } return new nasl.Identifier(); throw new console_1.error('panic: unimplemented in dispatchToNaslExpr.'); } const toNaslIdentifier = ([e]) => { const ni = new nasl.Identifier({ name: e.name }); ni.qName = e; // 非本身的属性,不能直接在初始化时构造 return (0, common_util_1.PackNaslAndCst)(ni, (0, common_util_1.TYPE)('TermRef', e)); }; exports.toNaslIdentifier = toNaslIdentifier; const toNaslIntegerLit = (e) => { const nil = new nasl.NumericLiteral({ value: String(e), typeAnnotation: (0, common_util_1.getNasl)((0, to_nasl_type_1.namedTypeToNaslTypeAnno)((0, common_util_1.createQIdentifier)('Integer'), [])), }); return (0, common_util_1.PackNaslAndCst)(nil, e); }; exports.toNaslIntegerLit = toNaslIntegerLit; const toNaslDecimalLit = (e) => { const ndl = new nasl.NumericLiteral({ value: String(e), typeAnnotation: (0, common_util_1.getNasl)((0, to_nasl_type_1.namedTypeToNaslTypeAnno)((0, common_util_1.createQIdentifier)('Decimal'), [])), }); return (0, common_util_1.PackNaslAndCst)(ndl, e); }; exports.toNaslDecimalLit = toNaslDecimalLit; const toNaslNullLit = ([e]) => { return (0, common_util_1.PackNaslAndCst)(new nasl.NullLiteral(), e); }; exports.toNaslNullLit = toNaslNullLit; // 这里就是两层[[.]] const toNaslBooleanLit = ([[e]]) => { const nb = new nasl.BooleanLiteral({ value: String(e.value) }); return (0, common_util_1.PackNaslAndCst)(nb, e.value); }; exports.toNaslBooleanLit = toNaslBooleanLit; // fromStringLit const toNaslStringLit = ([e]) => { const ns = new nasl.StringLiteral({ value: e[0].value }); return (0, common_util_1.PackNaslAndCst)(ns, e[0].value); }; exports.toNaslStringLit = toNaslStringLit; const toNaslStringInterpolation = (d) => { let res = { __type: 'StringInterpolation', parts: [] }; let buf = ''; d.forEach((elem, idx) => { if (elem.__type !== 'Expression') { buf += elem.str; } else { if (buf.length > 0) { res.parts.push((0, common_util_1.PackNaslAndCst)(new nasl.StringLiteral({ value: buf }), { __type: 'String', str: buf })); buf = ''; } res.parts.push(elem.expr); } }); if (buf.length > 0) { res.parts.push((0, common_util_1.PackNaslAndCst)(new nasl.StringLiteral({ value: buf }), { __type: 'String', str: buf })); } const nInterpolation = new nasl.StringInterpolation({ expressions: res.parts.map(common_util_1.getNasl) }); return (0, common_util_1.PackNaslAndCst)(nInterpolation, (0, common_util_1.TYPE)('StringInterpolation', res.parts.map(common_util_1.getCst))); }; exports.toNaslStringInterpolation = toNaslStringInterpolation; const toNaslUnparsed = (str) => (0, common_util_1.PackNaslAndCst)(new nasl.Unparsed({ "code": str }), { __type: 'JSString', str }); exports.toNaslUnparsed = toNaslUnparsed; const toNaslArrayLit = (exprs, ty) => { const nL = new nasl.NewList({ items: exprs?.nasl }); if (ty) { nL.typeAnnotation = ty.nasl; nL.typeAnnotation.inferred = false; } return (0, common_util_1.PackNaslAndCst)(nL, (0, common_util_1.TYPE)('ArrayLit', { exprs: exprs?.cst, ty: ty?.cst ?? undefined })); }; exports.toNaslArrayLit = toNaslArrayLit; const toNaslMapLit = ([entries]) => { const nm = new nasl.NewMap({ keys: entries.nasl.map(entry => entry.key), // 我™还是得给打散成 pair…… values: entries.nasl.map(entry => entry.val) }); return (0, common_util_1.PackNaslAndCst)(nm, (0, common_util_1.TYPE)('MapLit', entries.cst)); }; exports.toNaslMapLit = toNaslMapLit; // isEnumIntRef. please generate code without const toNaslEnumIntRef = ([namespaceArr, _digitName]) => { let enumTypeName = namespaceArr[0]; // 暂时先支持两种写法吧 if (namespaceArr.length > 2 && namespaceArr[0] === 'app' && namespaceArr[1] === 'enums') { enumTypeName = namespaceArr[2]; } const value = _digitName.nasl.value; const enumIntRef = new nasl.CstIntEnumRef(enumTypeName, value); return (0, common_util_1.PackNaslAndCst)(enumIntRef, (0, common_util_1.TYPE)('EnumIntRef', { namespace: namespaceArr, name: _digitName.cst })); }; exports.toNaslEnumIntRef = toNaslEnumIntRef; const toNaslEmptyBrackets = _ => (0, common_util_1.PackNaslAndCst)(new nasl.EmptyBrackets(), (0, common_util_1.TYPE)('EmptyBrackets', { expr: '[]' })); exports.toNaslEmptyBrackets = toNaslEmptyBrackets; // CompoundLambda or AnonymousStructure // export const toNaslEmptyBraces = _ => PackNaslAndCst(new nasl.EmptyBraces(), TYPE('EmptyBraces', { expr: '{}' })) const toNaslAnonymousFunc = (e) => { const nl = new nasl.AnonymousFunction({ params: e.params.map(to_nasl_statement_1.toNaslValueParam), // @ts-ignore body: dispatchToNaslExpr(e.nasl.expr), // last expression }); return (0, common_util_1.PackNaslAndCst)(nl, (0, common_util_1.TYPE)('AnonymousFunction', e)); }; exports.toNaslAnonymousFunc = toNaslAnonymousFunc; const toNaslCallQueryComponent = (e) => (0, common_util_1.PackNaslAndCst)(toNaslCallQueryComponentImpl(e.nasl), (0, common_util_1.TYPE)('CallQueryComponent', e.cst)); exports.toNaslCallQueryComponent = toNaslCallQueryComponent; const toNaslBinaryExpr = (left, op, right) => { const nb = new nasl.BinaryExpression(); // @ts-ignore Nasl 未定义 Pow 幂运算 运算符 ^ nb.operator = op.toLowerCase(); // 牛的,必须用 startwith 而非 startWith nb.left = left.nasl; nb.right = right.nasl; return (0, common_util_1.PackNaslAndCst)(nb, (0, common_util_1.TYPE)(binaryOpToName.get(op), { left: left.cst, op, right: right.cst })); }; exports.toNaslBinaryExpr = toNaslBinaryExpr; const BuildBinary = ([left, op, _1, right]) => { if (Array.isArray(op)) { op = op[0].value; } else { op = op.value; } return (0, exports.toNaslBinaryExpr)(left, op, right); }; exports.BuildBinary = BuildBinary; const toNaslCallSuffix = ([tyArgs, valArgs]) => { const res = (0, common_util_1.AutoPackNaslAndCst)({ tyArgs, valArgs }); (0, common_util_1.TYPE)('CallSuffix', res.cst); return res; }; exports.toNaslCallSuffix = toNaslCallSuffix; const toNaslArrayAccessSuffix = ([expr]) => (0, common_util_1.PackNaslAndCst)(expr.nasl, (0, common_util_1.TYPE)('ArrayAccessSuffix', { expr: expr.cst })); exports.toNaslArrayAccessSuffix = toNaslArrayAccessSuffix; const toNaslMemberAccessSuffix = (rawIdent) => (0, common_util_1.PackNaslAndCst)((0, exports.toNaslIdentifier)([(0, common_util_1.createQIdentifier)(rawIdent)]).nasl, (0, common_util_1.TYPE)('MemberAccessSuffix', { rawIdent })); exports.toNaslMemberAccessSuffix = toNaslMemberAccessSuffix; const toNaslSQLFilterSuffix = () => (0, common_util_1.PackNaslAndCst)(null, (0, common_util_1.TYPE)('SQLFilterSuffix', {})); exports.toNaslSQLFilterSuffix = toNaslSQLFilterSuffix; // 第一轮 toAST 先简单处理,后续 refine-nasl-ast 会细分不同的 call const toNaslCallLogic = (callee, sfx) => { if ((0, asserts_1.isAnonymousFunction)(callee.nasl)) { throw new Error('Nasl AST 暂时无法承载, AnonymousFunction cannot be called'); } // console.log('CALLER NASL NAMESPACE', caller.nasl); const callerNsp = callee.nasl.qName.namespace.join(common_util_1.NAMESPACE_SEP_AST); const nc = new nasl.CallLogic({ calleeName: callee.nasl.name, calleeNamespace: callerNsp ?? common_util_1.APP_LOGICS_AST, arguments: sfx.nasl.valArgs, typeArguments: sfx.nasl.tyArgs, }); if ((0, asserts_1.isIdentifier)(callee.nasl)) { nc.qName = callee.nasl.qName; } else { // lambda literal { -> }(x) // Nasl AST 暂时无法承载 // nc.simpleLambda = caller; } // if (isEmpty(nc.typeArguments)) { // nc.typeArguments = null; // } nc.handleError = false; return (0, common_util_1.PackNaslAndCst)(nc, (0, common_util_1.TYPE)('CallLogic', { caller: callee.cst, sfx: sfx.cst })); }; exports.toNaslCallLogic = toNaslCallLogic; const toNaslArrayAccess = (expr, sfx) => { const valArg = (0, exports.toNaslValArg)(sfx); const ncf = new nasl.CallFunction({ calleeName: 'Get', arguments: [ new nasl.Argument({ expression: expr.nasl }), valArg.nasl ] }); return (0, common_util_1.PackNaslAndCst)(ncf, (0, common_util_1.TYPE)('ArrayAccess', { expr: expr.cst, suffix: valArg.cst })); }; const toNaslMemberAccess = (expr, sfx) => { const nme = new nasl.MemberExpression({ object: expr.nasl, property: sfx.nasl }); return (0, common_util_1.PackNaslAndCst)(nme, (0, common_util_1.TYPE)('MemberAccess', { obj: expr.cst, prop: sfx.cst })); }; const toNaslSQLFilter = (expr) => { const nue = new nasl.UnaryExpression({ operator: 'isNull', // 这里又有大写啦 argument: expr.nasl }); return (0, common_util_1.PackNaslAndCst)(nue, (0, common_util_1.TYPE)('SQLFilter', { expr: expr.cst })); }; const toNaslValArg = (expr, name) => { const na = new nasl.Argument({ expression: expr.nasl }); if (name) { na.keyword = name; } // console.log('toNaslValArg', na.keyword); return (0, common_util_1.PackNaslAndCst)(na, (0, common_util_1.TYPE)('ValueArg', { expr: expr.cst, name })); }; exports.toNaslValArg = toNaslValArg; const toNaslValArgList = (args, lam) => { if (!args?.nasl) { args = {}; args.nasl = []; args.cst = []; } if (lam) { return (0, common_util_1.PackNaslAndCst)(args.nasl.concat(lam.nasl), args.cst.concat(lam.cst)); } else { return (0, common_util_1.PackNaslAndCst)(args.nasl, args.cst); } }; exports.toNaslValArgList = toNaslValArgList; // export const toNaslTyArg = ([arg]) => // PackNaslAndCst(arg.nasl, TYPE('TypeArg', arg.cst)) // export const toNaslTyArgList = ([args]) => PackNaslAndCst(args.nasl, args.cst) exports.toNaslDefaultValue = undefined; const toNaslSubLogic = (body, params) => { const nl = new nasl.Logic({ name: null, params: params?.nasl, returns: [], // TODO body: [new nasl.Start(), body.nasl.stmts, new nasl.End()], variables: body.nasl.vars }); return (0, common_util_1.PackNaslAndCst)(nl, (0, common_util_1.TYPE)('SubLogic', { params: params?.cst, body: body.cst })); }; exports.toNaslSubLogic = toNaslSubLogic; const toNaslLambda = (expr, params) => { const nl = new nasl.AnonymousFunction({ params: params?.nasl, body: expr.nasl }); // const nb = new nasl.BinaryExpression(); // // @ts-ignore Nasl 未定义 Pow 幂运算 运算符 ^ // nb.operator = op.toLowerCase(); // 牛的,必须用 startwith 而非 startWith // nb.left = left.nasl; // nb.right = right.nasl; // return PackNaslAndCst(nb, TYPE(binaryOpToName.get(op), { left: left.cst, op, right: right.cst })); return (0, common_util_1.PackNaslAndCst)(nl, (0, common_util_1.TYPE)('Lambda', { expr: expr.cst, params: params?.cst })); }; exports.toNaslLambda = toNaslLambda; const toNaslLamParam = (name, ty) => { const np = new nasl.Param({ name: name, typeAnnotation: ty?.nasl ?? null, // 难伺候 // defaultValue: null }); return (0, common_util_1.PackNaslAndCst)(np, (0, common_util_1.TYPE)('Param', { name, ty: ty?.cst })); }; exports.toNaslLamParam = toNaslLamParam; const toNaslLogicParam = ([varInit]) => { const nv = varInit.nasl; const np = new nasl.Param({ name: nv.name, typeAnnotation: nv.typeAnnotation, defaultValue: nv.defaultValue, defaultExpression: nv.defaultValue?.expression }); // if (e.anns) { // // @ts-ignore // np.annotations = e.anns; // } return (0, common_util_1.PackNaslAndCst)(np, (0, common_util_1.TYPE)('Param', varInit.cst)); }; exports.toNaslLogicParam = toNaslLogicParam; // transform type variables introduced in <·> to type parameters // not to be confused with types used <·> at the use site const toNaslTyParam = (ty) => (0, common_util_1.PackNaslAndCst)(new nasl.TypeParam({ name: ty }), (0, common_util_1.TYPE)("TypeParam", { ty })); exports.toNaslTyParam = toNaslTyParam; const toNaslPrefix = (expr) => { const e = new nasl.UnaryExpression({ operator: '!', argument: expr.nasl }); return (0, common_util_1.PackNaslAndCst)(e, (0, common_util_1.TYPE)('Prefix', expr.cst)); }; exports.toNaslPrefix = toNaslPrefix; //# sourceMappingURL=to-nasl-expression.js.map