From b2f7e1b34b9bd8e9dbcab5910e6dd244fd544882 Mon Sep 17 00:00:00 2001 From: Ben Baryo <60312583+BenBaryoPX@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:41:12 +0200 Subject: [PATCH] TypeMap (#32) * Update dependencies * Add the typemap feature * 2.1.0 --- README.md | 1 + package-lock.json | 20 ++++++++++---------- package.json | 6 +++--- src/flast.js | 6 +++++- src/types.js | 1 + tests/parsing.test.js | 18 ++++++++++++++++++ 6 files changed, 38 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 45fc263..b846bc6 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ npm install - Tracks scope and connects each declaration to its references. See [eslint-scope](https://github.com/eslint/eslint-scope) for more info on the scopes used. - Adds a unique id to each node to simplify tracking and understanding relations between nodes. +- Maps the types to the nodes for easier access. - Arborist - marks nodes for replacement or deletion and applies all changes in a single iteration over the tree. ### flAST Data Structure diff --git a/package-lock.json b/package-lock.json index b4d291d..7307372 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,21 @@ { "name": "flast", - "version": "2.0.3", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "flast", - "version": "2.0.3", + "version": "2.1.0", "license": "MIT", "dependencies": { "escodegen": "npm:@javascript-obfuscator/escodegen", - "eslint-scope": "^8.1.0", + "eslint-scope": "^8.2.0", "espree": "^10.3.0", "estraverse": "^5.3.0" }, "devDependencies": { - "eslint": "^9.12.0", + "eslint": "^9.14.0", "husky": "^9.1.6" } }, @@ -196,9 +196,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.0.tgz", - "integrity": "sha512-xnRgu9DxZbkWak/te3fcytNyp8MTbuiZIaueg2rgEvBuN55n04nwLYLU9TX/VVlusc9L2ZNXi99nUFNkHXtr5g==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -366,9 +366,9 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 58be281..d048a4b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flast", - "version": "2.0.3", + "version": "2.1.0", "description": "Flatten JS AST", "main": "src/index.js", "type": "module", @@ -27,12 +27,12 @@ "homepage": "https://github.com/PerimeterX/flast#readme", "dependencies": { "escodegen": "npm:@javascript-obfuscator/escodegen", - "eslint-scope": "^8.1.0", + "eslint-scope": "^8.2.0", "espree": "^10.3.0", "estraverse": "^5.3.0" }, "devDependencies": { - "eslint": "^9.12.0", + "eslint": "^9.14.0", "husky": "^9.1.6" } } diff --git a/src/flast.js b/src/flast.js index bd43896..98a92b9 100644 --- a/src/flast.js +++ b/src/flast.js @@ -19,7 +19,7 @@ function parseCode(inputCode, opts = {}) { const excludedParentKeys = [ 'type', 'start', 'end', 'range', 'sourceType', 'comments', 'srcClosure', 'nodeId', - 'childNodes', 'parentNode', 'parentKey', 'scope', + 'childNodes', 'parentNode', 'parentKey', 'scope', 'typeMap', 'lineage', 'allScopes', ]; /** @@ -123,6 +123,7 @@ function extractNodesFromRoot(rootNode, opts) { opts = { ...generateFlatASTDefaultOptions, ...opts }; const tree = []; let nodeId = 0; + const typeMap = {}; // noinspection JSUnusedGlobalSymbols estraverse.traverse(rootNode, { @@ -133,6 +134,8 @@ function extractNodesFromRoot(rootNode, opts) { enter(node, parentNode) { tree.push(node); node.nodeId = nodeId++; + if (!typeMap[node.type]) typeMap[node.type] = [node]; + else typeMap[node.type].push(node); node.childNodes = []; node.parentNode = parentNode; node.parentKey = parentNode ? getParentKey(node) : ''; @@ -146,6 +149,7 @@ function extractNodesFromRoot(rootNode, opts) { }); } }); + if (tree?.length) tree[0].typeMap = typeMap; return tree; } diff --git a/src/types.js b/src/types.js index 7836095..b4f679f 100644 --- a/src/types.js +++ b/src/types.js @@ -73,6 +73,7 @@ import {Scope} from 'eslint-scope'; * @property {ASTNode} [test] * @property {ASTNode} [tokens] * @property {Object[]} [trailingComments] + * @property {Object} [typeMap] * @property {ASTNode} [update] * @property {ASTNode|string|number|boolean} [value] */ diff --git a/tests/parsing.test.js b/tests/parsing.test.js index 9b21754..962c2a6 100644 --- a/tests/parsing.test.js +++ b/tests/parsing.test.js @@ -55,4 +55,22 @@ describe('Parsing tests', () => { const result = generateCode(ast[0]); assert.strictEqual(result, expected); }); + it(`Verify the type map is generated accurately`, () => { + const code = `class a { + static b = 1; + #c = 2; +}`; + const ast = generateFlatAST(code); + const expected = { + Program: [ast[0]], + ClassDeclaration: [ast[1]], + Identifier: [ast[2], ast[5]], + ClassBody: [ast[3]], + PropertyDefinition: [ast[4], ast[7]], + Literal: [ast[6], ast[9]], + PrivateIdentifier: [ast[8]], + }; + const result = ast[0].typeMap; + assert.deepEqual(result, expected); + }); }); \ No newline at end of file