Skip to content

Commit

Permalink
Prevent exceptions from being thrown on invalid code (#33)
Browse files Browse the repository at this point in the history
* Update dependencies
* Fix issue where invalid code would throw an exception. Now it will print a debug error message instead.
* Add tests on Node 22.x
  • Loading branch information
BenBaryoPX authored Dec 9, 2024
1 parent b2f7e1b commit efaac80
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

strategy:
matrix:
node-version: [18.x, 20.x]
node-version: [18.x, 20.x, 22.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
Expand Down
99 changes: 47 additions & 52 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"estraverse": "^5.3.0"
},
"devDependencies": {
"eslint": "^9.14.0",
"husky": "^9.1.6"
"eslint": "^9.16.0",
"husky": "^9.1.7"
}
}
33 changes: 20 additions & 13 deletions src/flast.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {parse} from 'espree';
import {generate, attachComments} from 'escodegen';
import estraverse from 'estraverse';
import {analyze} from 'eslint-scope';
import {logger} from './utils/logger.js';
import {generate, attachComments} from 'escodegen';

const ecmaVersion = 'latest';
const sourceType = 'module';
Expand Down Expand Up @@ -74,12 +75,15 @@ function createSrcClosure(src) {
*/
function generateFlatAST(inputCode, opts = {}) {
opts = { ...generateFlatASTDefaultOptions, ...opts };
let tree = [];
const rootNode = generateRootNode(inputCode, opts);
const tree = extractNodesFromRoot(rootNode, opts);
if (opts.detailed) {
const scopes = getAllScopes(rootNode);
for (let i = 0; i < tree.length; i++) injectScopeToNode(tree[i], scopes);
tree[0].allScopes = scopes;
if (rootNode) {
tree = extractNodesFromRoot(rootNode, opts);
if (opts.detailed) {
const scopes = getAllScopes(rootNode);
for (let i = 0; i < tree.length; i++) injectScopeToNode(tree[i], scopes);
tree[0].allScopes = scopes;
}
}
return tree;
}
Expand Down Expand Up @@ -115,6 +119,7 @@ function generateRootNode(inputCode, opts = {}) {
if (opts.includeSrc) rootNode.srcClosure = createSrcClosure(inputCode);
} catch (e) {
if (opts.alernateSourceTypeOnFailure && e.message.includes('in strict mode')) rootNode = parseCode(inputCode, {...parseOpts, sourceType: 'script'});
else logger.debug(e);
}
return rootNode;
}
Expand Down Expand Up @@ -279,15 +284,17 @@ function matchScopeToNode(node, allScopes) {
*/
async function generateFlatASTAsync(inputCode, opts = {}) {
opts = { ...generateFlatASTDefaultOptions, ...opts };
const rootNode = generateRootNode(inputCode, opts);
const tree = extractNodesFromRoot(rootNode, opts);
let tree = [];
const promises = [];
if (opts.detailed) {
const scopes = getAllScopes(rootNode);
for (let i = 0; i < tree.length; i++) {
promises.push(injectScopeToNodeAsync(tree[i], scopes));
const rootNode = generateRootNode(inputCode, opts);
if (rootNode) {
tree = extractNodesFromRoot(rootNode, opts);
if (opts.detailed) {
const scopes = getAllScopes(rootNode);
for (let i = 0; i < tree.length; i++) {
promises.push(injectScopeToNodeAsync(tree[i], scopes));
}
}

}
return Promise.all(promises).then(() => tree);
}
Expand Down
11 changes: 11 additions & 0 deletions tests/functionality.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,15 @@ describe('Functionality tests', () => {
assert.equal(unparsedAst.length, 0, `Script was not parsed.${unparsedError ? 'Error: ' + unparsedError : ''}`);
assert.ok(parsedAst.length, `Script was not parsed.${parsedError ? 'Error: ' + parsedError : ''}`);
});
it(`Verify generateFlatAST doesn't throw an exception for invalid code`, () => {
const code = `return a;`;
let result;
const expectedResult = [];
try {
result = generateFlatAST(code, {alernateSourceTypeOnFailure: false});
} catch (e) {
result = e.message;
}
assert.deepStrictEqual(result, expectedResult);
});
});

0 comments on commit efaac80

Please sign in to comment.