UNPKG

@lcap/nasl-parser

Version:

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

141 lines 5.99 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.leaveNamespace = exports.addEnumCons = exports.addResolvedNode = exports.CompilerEnvInfo = void 0; exports.collectAllGlobalDefinitions = collectAllGlobalDefinitions; exports.addRefTypeSemInfo = addRefTypeSemInfo; exports.addConstructor = addConstructor; const nasl = __importStar(require("@lcap/nasl")); const env_stack_1 = require("./env-stack"); const decorated_nasl_ast_1 = require("./decorated-nasl-ast"); const common_util_1 = require("./common-util"); // 大致思路:node string name ---> define-side node ---> semantic information class CompilerEnvInfo { // node 的 hash 到 node 的语义信息的映射 semInfo = new Map(); // string 表示的名字到定义处的 node hash 的映射,因为 shadow 等特性,是个一对多结构 resolvedNodes = new env_stack_1.Env(i => i); // 现阶段所有已经打开的 namespace,每个 namespace 用 Array<string> 表示,如 ['nasl', 'core'] // using nasl.core 生成 [['nasl', 'core']],但不会生成 [['nasl', 'core'], ['core']] 这种结构 namespaceOpen = []; // 现在所处的 namespace,如对于 namespace nasl { namespace core { #1 }; namespace util { #2 } }, // #1 处于 ['nasl', 'core'],#2 处于 ['nasl', 'util'] currNamespace = []; // 记录函数的形参和局部变量,这些信息离开函数体后即删除,可减少符号表的体积加快查找速度。 // 双层 Array 支持嵌套作用域,每个作用域一个 Array<QVarName> localVars = [[]]; } exports.CompilerEnvInfo = CompilerEnvInfo; // nd : nasl nodes + cst nodes function collectAllGlobalDefinitions(cei, nd) { if (nd instanceof nasl.Logic || nd instanceof nasl.LogicDeclaration) { // env 里添加函数签名 addLogicSigBinding(cei, nd); } // no nasl.Function in this phase if (nd instanceof nasl.Entity || nd instanceof nasl.Structure) { (0, exports.addResolvedNode)(cei, nd); addRefTypeSemInfo(cei, nd); addConstructor(cei, nd); } if (nd instanceof nasl.Enum) { (0, exports.addResolvedNode)(cei, nd); (0, exports.addEnumCons)(cei, nd); } if (nd instanceof decorated_nasl_ast_1.CstNamespace) { (0, exports.addResolvedNode)(cei, nd); cei.currNamespace.push(nd.name); } } const addResolvedNode = (cei, nd) => { const nodeName = nd.name ?? nd.value; // EnumItem 没有 name 只有 value cei.semInfo.set(nd, { namespace: (0, common_util_1.SimpleSillyDeepClone)(cei.currNamespace), name: nodeName, isConst: false, }); cei.resolvedNodes.add((0, common_util_1.prependNamespace)(cei.currNamespace, nodeName), nd); }; exports.addResolvedNode = addResolvedNode; const addEnumCons = (cei, ne) => { cei.currNamespace.push(ne.name); ne.enumItems.forEach(ei => { (0, exports.addResolvedNode)(cei, ei); }); cei.currNamespace.pop(); }; exports.addEnumCons = addEnumCons; // Add a function's signature to our symbol table. const addLogicSigBinding = (cei, nl) => { // env 里添加函数签名 if (nl.name) { cei.resolvedNodes.add((0, common_util_1.prependNamespace)(cei.currNamespace, nl.name), nl); const nsi = { namespace: (0, common_util_1.SimpleSillyDeepClone)(cei.currNamespace), // 调了半天,原来是忘了 clone name: nl.name, isConst: false, }; nsi['type'] = new nasl.TypeAnnotation({ typeKind: 'function', typeArguments: nl?.params?.map(p => p.typeAnnotation), }); // 用户标注返回类型 if (nl.returns && !(0, common_util_1.isEmpty)(nl.returns) && (0, common_util_1.head)(nl.returns)) { nsi['type'].returnType = [(0, common_util_1.head)(nl.returns).typeAnnotation]; } else { // 未标注返回类型,先当做无返回吧 nsi['type'].returnType = [new nasl.TypeAnnotation({ typeKind: 'primitive', typeNamespace: common_util_1.NASL_CORE_NL, typeName: 'void', })]; } cei.semInfo.set(nl, nsi); } return nl; }; const leaveNamespace = (cei, cns) => { if (cns instanceof decorated_nasl_ast_1.CstNamespace) { cei.currNamespace.pop(); } return cns; }; exports.leaveNamespace = leaveNamespace; function addRefTypeSemInfo(cei, nd) { const nsi = { name: nd.name, namespace: (0, common_util_1.SimpleSillyDeepClone)(cei.currNamespace), isConst: false, }; cei.semInfo.set(nd, nsi); cei.resolvedNodes.add(nd.name, nd); } function addConstructor(cei, nd) { const ctorName = `${(0, common_util_1.prependNamespace)(cei.currNamespace, nd.name)}.constructor`; cei.resolvedNodes.add(ctorName, nd); return nd; } //# sourceMappingURL=resolve-global-bindings.js.map