diff --git a/package-lock.json b/package-lock.json index 51a9a5a..52b37b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "flast", - "version": "2.2.1", + "version": "2.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "flast", - "version": "2.2.1", + "version": "2.2.2", "license": "MIT", "dependencies": { "escodegen": "npm:@javascript-obfuscator/escodegen", @@ -14,7 +14,7 @@ "espree": "^10.3.0" }, "devDependencies": { - "eslint": "^9.16.0", + "eslint": "^9.18.0", "husky": "^9.1.7" } }, @@ -76,9 +76,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", - "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -113,9 +113,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", - "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", + "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", "dev": true, "license": "MIT", "engines": { @@ -133,12 +133,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", - "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@eslint/core": "^0.10.0", "levn": "^0.4.1" }, "engines": { @@ -439,19 +440,19 @@ } }, "node_modules/eslint": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", - "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", + "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.9.0", + "@eslint/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.17.0", - "@eslint/plugin-kit": "^0.2.3", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", diff --git a/package.json b/package.json index ca60541..938be64 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flast", - "version": "2.2.1", + "version": "2.2.2", "description": "Flatten JS AST", "main": "src/index.js", "type": "module", @@ -31,7 +31,7 @@ "espree": "^10.3.0" }, "devDependencies": { - "eslint": "^9.16.0", + "eslint": "^9.18.0", "husky": "^9.1.7" } } diff --git a/src/flast.js b/src/flast.js index 1890bd6..0b42c73 100644 --- a/src/flast.js +++ b/src/flast.js @@ -120,7 +120,7 @@ function extractNodesFromRoot(rootNode, opts) { const node = stack.shift(); if (node.nodeId) continue; node.childNodes = node.childNodes || []; - const childrenLoc = {}; // Store the location of child nodes to sort them by order + const childrenLoc = {}; // Store the location of child nodes to sort them by order node.parentKey = node.parentKey || ''; // Make sure parentKey exists // Iterate over all keys of the node to find child nodes const keys = Object.keys(node); @@ -134,6 +134,7 @@ function extractNodesFromRoot(rootNode, opts) { if (Array.isArray(content)) { for (let j = 0; j < content.length; j++) { const childNode = content[j]; + if (!childNode) continue; childNode.parentNode = node; childNode.parentKey = key; childrenLoc[childNode.start] = childNode; @@ -154,7 +155,7 @@ function extractNodesFromRoot(rootNode, opts) { typeMap[node.type] = typeMap[node.type] || []; typeMap[node.type].push(node); if (opts.detailed) { - node.scope = matchScopeToNode(node, scopes); + node.scope = scopes[node.scopeId] || node.parentNode?.scope; node.lineage = [...node.parentNode?.lineage || []]; if (!node.lineage.includes(node.scope.scopeId)) { node.lineage.push(node.scope.scopeId); @@ -255,7 +256,7 @@ function getAllScopes(rootNode) { const stack = [globalScope]; while (stack.length) { const scope = stack.shift(); - if (scope.type !== 'module') { + if (scope.type !== 'module' && !scope.type.includes('-name')) { scope.scopeId = scopeId++; scope.block.scopeId = scope.scopeId; allScopes[scope.scopeId] = allScopes[scope.scopeId] || scope; @@ -279,30 +280,6 @@ function getAllScopes(rootNode) { return rootNode.allScopes = allScopes; } -/** - * @param {ASTNode} node - * @param {{number: ASTScope}} allScopes - * @return {ASTScope} - */ -function matchScopeToNode(node, allScopes) { - let scope = node.scope; - if (!scope) { - let scopeBlock = node; - while (scopeBlock && scopeBlock.scopeId === undefined) { - scopeBlock = scopeBlock.parentNode; - } - if (scopeBlock) { - scope = allScopes[scopeBlock.scopeId]; - } - } - if (scope) { - if (scope.type.includes('-name') && scope?.childScopes?.length === 1) scope = scope.childScopes[0]; - if (node === scope.block && scope.upper) scope = scope.upper; - if (scope.type === 'module') scope = scope.upper; - } else scope = allScopes[0]; // Global scope - this should never be reached - return scope; -} - export { extractNodesFromRoot, generateCode, diff --git a/tests/parsing.test.js b/tests/parsing.test.js index 362b766..912cee9 100644 --- a/tests/parsing.test.js +++ b/tests/parsing.test.js @@ -104,4 +104,9 @@ describe('Parsing tests', () => { assert.deepEqual(n.lineage, extractedLineage); }); }); + it(`Verify null childNodes are correctly parsed`, () => { + const code = `[,,,].join('-');`; + const ast = generateFlatAST(code); + assert.notEqual(ast, [1]); + }); }); \ No newline at end of file