diff --git a/lib/lbt/analyzer/JSModuleAnalyzer.js b/lib/lbt/analyzer/JSModuleAnalyzer.js index 0817b59b0..84b1a0b0c 100644 --- a/lib/lbt/analyzer/JSModuleAnalyzer.js +++ b/lib/lbt/analyzer/JSModuleAnalyzer.js @@ -64,6 +64,7 @@ const EnrichedVisitorKeys = (function() { BreakStatement: [], CallExpression: [], // special handling CatchClause: ["param", "body"], + ChainExpression: [], ClassBody: [], ClassDeclaration: [], ClassExpression: [], @@ -125,8 +126,10 @@ const EnrichedVisitorKeys = (function() { * All properties in an object pattern are executed. */ ObjectPattern: [], // properties + // PrivateIdentifier: [], // will come with ES2022 Program: [], Property: [], + // PropertyDefinition: [], // will come with ES2022 /* * argument of the rest element is always executed under the same condition as the rest element itself */ @@ -134,6 +137,7 @@ const EnrichedVisitorKeys = (function() { ReturnStatement: [], SequenceExpression: [], SpreadElement: [], // the argument of the spread operator always needs to be evaluated - argument + // StaticBlock: [], // will come with ES2022 Super: [], SwitchStatement: [], SwitchCase: ["test", "consequent"], // test and consequent are executed only conditionally @@ -174,6 +178,9 @@ const EnrichedVisitorKeys = (function() { // Check if the visitor-key exists in the available Syntax because // the list of visitor-keys does not match the available Syntax. if (!Syntax[type]) { + // Deprecated / removed: + // ExperimentalRestProperty + // ExperimentalSpreadProperty return; } // Ignore JSX visitor-keys because they aren't used. diff --git a/lib/lbt/utils/parseUtils.js b/lib/lbt/utils/parseUtils.js index 8e8f796a4..4f072c4e1 100644 --- a/lib/lbt/utils/parseUtils.js +++ b/lib/lbt/utils/parseUtils.js @@ -9,7 +9,7 @@ function parseJS(code, userOptions = {}) { // allowed options and their defaults const options = { comment: false, - ecmaVersion: 2020, + ecmaVersion: 2021, range: false, sourceType: "script", }; diff --git a/package-lock.json b/package-lock.json index 4e5399a9a..2f2c94069 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "cheerio": "1.0.0-rc.9", "escape-unicode": "^0.2.0", "escope": "^3.6.0", - "espree": "^6.2.1", + "espree": "^9.3.0", "globby": "^11.1.0", "graceful-fs": "^4.2.9", "jsdoc": "^3.6.7", @@ -518,20 +518,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/@eslint/eslintrc/node_modules/espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", - "dev": true, - "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", @@ -2940,7 +2926,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2951,20 +2936,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/eslint/node_modules/espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", - "dev": true, - "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3017,35 +2988,16 @@ } }, "node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/esprima": { @@ -7996,17 +7948,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", - "dev": true, - "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" - } - }, "globals": { "version": "13.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", @@ -9842,17 +9783,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", - "dev": true, - "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" - } - }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -9949,29 +9879,16 @@ "eslint-visitor-keys": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", - "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", - "dev": true + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==" }, "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" } }, "esprima": { diff --git a/package.json b/package.json index fb9603787..92eed1ea8 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "cheerio": "1.0.0-rc.9", "escape-unicode": "^0.2.0", "escope": "^3.6.0", - "espree": "^6.2.1", + "espree": "^9.3.0", "globby": "^11.1.0", "graceful-fs": "^4.2.9", "jsdoc": "^3.6.7", diff --git a/test/fixtures/lbt/modules/es6-syntax.js b/test/fixtures/lbt/modules/es6-syntax.js index 5d6914f9b..2f9924594 100644 --- a/test/fixtures/lbt/modules/es6-syntax.js +++ b/test/fixtures/lbt/modules/es6-syntax.js @@ -40,4 +40,9 @@ sap.ui.define([ await Promise.resolve(); }; + // chain expression + if (m1?.foo?.bar) { + sap.ui.require(["conditional/module4"]); + } + }); diff --git a/test/lib/lbt/analyzer/JSModuleAnalyzer.js b/test/lib/lbt/analyzer/JSModuleAnalyzer.js index 93bd8bcef..10b5da6e5 100644 --- a/test/lib/lbt/analyzer/JSModuleAnalyzer.js +++ b/test/lib/lbt/analyzer/JSModuleAnalyzer.js @@ -493,6 +493,7 @@ test("ES6 Syntax", (t) => { "conditional/module1.js", "conditional/module2.js", "conditional/module3.js", + "conditional/module4.js", "static/module1.js", "static/module2.js", "static/module3.js", diff --git a/test/lib/lbt/utils/parseUtils.js b/test/lib/lbt/utils/parseUtils.js index 3971d763e..eec63d66d 100644 --- a/test/lib/lbt/utils/parseUtils.js +++ b/test/lib/lbt/utils/parseUtils.js @@ -18,3 +18,9 @@ test("successful parse step", (t) => { t.true(ast != null && typeof ast === "object"); t.is(ast.type, "Program"); }); + +test("successful parse step (ES2021 features)", (t) => { + const ast = parseJS("const x = 1_000_000_000;"); // numeric separators + t.true(ast != null && typeof ast === "object"); + t.is(ast.type, "Program"); +});