From 177df97a96f5b9e6af8ea08a26675233e679ab7e Mon Sep 17 00:00:00 2001 From: Florian Vogt Date: Fri, 5 Aug 2022 11:48:41 +0200 Subject: [PATCH] [INTERNAL] ASTUtils: Enable ObjectPattern and ArrayPattern as VariableDeclaration Id --- lib/lbt/utils/ASTUtils.js | 19 ++++++------ test/fixtures/lbt/modules/es6-syntax.js | 10 +++++++ test/lib/lbt/utils/ASTUtils.js | 39 ++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/lib/lbt/utils/ASTUtils.js b/lib/lbt/utils/ASTUtils.js index 705a14d97..edac90b68 100644 --- a/lib/lbt/utils/ASTUtils.js +++ b/lib/lbt/utils/ASTUtils.js @@ -47,18 +47,17 @@ function isNamedObject(node, objectPath, length) { } function isIdentifier(node, name) { - if ( node.type != Syntax.Identifier ) { - return false; - } - if ( typeof name == "string" ) { + if ( node.type === Syntax.Identifier && typeof name == "string" ) { return name === node.name; + } else if ( node.type === Syntax.Identifier && Array.isArray(name) ) { + return name.find((name) => name === node.name || name === "*") !== undefined; + } else if ( node.type === Syntax.ObjectPattern ) { + return node.properties.filter((childnode) => isIdentifier(childnode.key, name)).length > 0; + } else if ( node.type === Syntax.ArrayPattern ) { + return node.elements.filter((childnode) => isIdentifier(childnode, name)).length > 0; + } else { + return false; } - for (let i = 0; i < name.length; i++) { - if ( name[i] === node.name || name[i] === "*" ) { - return true; - } - } - return false; } function getPropertyKey(property) { diff --git a/test/fixtures/lbt/modules/es6-syntax.js b/test/fixtures/lbt/modules/es6-syntax.js index bfa035b90..71162d944 100644 --- a/test/fixtures/lbt/modules/es6-syntax.js +++ b/test/fixtures/lbt/modules/es6-syntax.js @@ -83,6 +83,16 @@ sap.ui.define([ // TODO: This is not detected as conditional dependency // m1 ?? sap.ui.require(['conditional/module11']); + // ObjectPattern as Id + const {module1, module2} = { + module1: sap.ui.require(['conditional/module1'], function(){}), + module2: sap.ui.require(['conditional/module1'], function(){}) + }; + // ArrayPattern as Id + const [module1a, module2b] = [ + sap.ui.require(['conditional/module1'], function(){}), + sap.ui.require(['conditional/module1'], function(){}) + ]; }); diff --git a/test/lib/lbt/utils/ASTUtils.js b/test/lib/lbt/utils/ASTUtils.js index 88ace87d9..faf936094 100644 --- a/test/lib/lbt/utils/ASTUtils.js +++ b/test/lib/lbt/utils/ASTUtils.js @@ -40,7 +40,7 @@ test("isBoolean", (t) => { t.false(ASTUtils.isBoolean(falseLiteral, true), "is a literal and value does not matches"); }); -test("isIdentifier", (t) => { +test("isIdentifier (identifier)", (t) => { const literal = parseJS("'testValue47'").body[0].expression; t.false(ASTUtils.isIdentifier(literal), "A literal is not an identifier"); @@ -58,6 +58,36 @@ test("isIdentifier", (t) => { t.false(ASTUtils.isIdentifier(identifier, [], "value does not match")); }); +test("isIdentifier (object pattern)", (t) => { + const identifier = parseJS("const { a, b } = { a: 'x', b: 'y' }").body[0].declarations[0].id; + + t.true(ASTUtils.isIdentifier(identifier, ["*"], "asterisk matches any string")); + t.true(ASTUtils.isIdentifier(identifier, ["a"], "value matches")); + t.true(ASTUtils.isIdentifier(identifier, "a"), "value matches"); + t.true(ASTUtils.isIdentifier(identifier, ["b"], "value matches")); + t.true(ASTUtils.isIdentifier(identifier, "b"), "value matches"); + + t.false(ASTUtils.isIdentifier(identifier, ""), "value does not match"); + t.false(ASTUtils.isIdentifier(identifier, "*"), "value does not match"); + t.false(ASTUtils.isIdentifier(identifier, "c"), "value does not match"); + t.false(ASTUtils.isIdentifier(identifier, [], "value does not match")); +}); + +test("isIdentifier (arry pattern)", (t) => { + const identifier = parseJS("const [ a, b ] = [ 'x', 'y' ]").body[0].declarations[0].id; + + t.true(ASTUtils.isIdentifier(identifier, ["*"], "asterisk matches any string")); + t.true(ASTUtils.isIdentifier(identifier, ["a"], "value matches")); + t.true(ASTUtils.isIdentifier(identifier, "a"), "value matches"); + t.true(ASTUtils.isIdentifier(identifier, ["b"], "value matches")); + t.true(ASTUtils.isIdentifier(identifier, "b"), "value matches"); + + t.false(ASTUtils.isIdentifier(identifier, ""), "value does not match"); + t.false(ASTUtils.isIdentifier(identifier, "*"), "value does not match"); + t.false(ASTUtils.isIdentifier(identifier, "c"), "value does not match"); + t.false(ASTUtils.isIdentifier(identifier, [], "value does not match")); +}); + test("isNamedObject", (t) => { const identifier = parseJS("testValue47").body[0].expression; @@ -136,6 +166,13 @@ test("getPropertyKey (spread element)", (t) => { "spread elements in object expressions should be ignored"); }); +test("getPropertyKey (object pattern)", (t) => { + const propertiesWithObjectPattern = + parseJS("const { a, b } = { a: 'x', b: 'y' }").body[0].declarations[0].init.properties; + t.is(ASTUtils.getPropertyKey(propertiesWithObjectPattern[0]), "a", + "object pattern in variable declaration"); +}); + test("findOwnProperty", (t) => { const literal = cleanse(parseJS("'x'").body[0].expression); const identifier = cleanse(parseJS("a").body[0].expression);