From 4d8a41cd1e91f9cc276060f7d3e1b5275a5715be Mon Sep 17 00:00:00 2001 From: Ben Baryo Date: Mon, 9 Dec 2024 14:05:03 +0200 Subject: [PATCH] Fix issue where invalid code would throw an exception. Now it will print a debug error message instead. --- src/flast.js | 33 ++++++++++++++++++++------------- tests/functionality.test.js | 11 +++++++++++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/flast.js b/src/flast.js index 98a92b9..c743751 100644 --- a/src/flast.js +++ b/src/flast.js @@ -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'; @@ -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; } @@ -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; } @@ -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); } diff --git a/tests/functionality.test.js b/tests/functionality.test.js index 43e485c..369969b 100644 --- a/tests/functionality.test.js +++ b/tests/functionality.test.js @@ -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); + }); }); \ No newline at end of file