@lcap/nasl-parser
Version:
Take Nasl text to Nasl AST with the help of generalized parsing.
141 lines • 5.99 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.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