From 631648ee0b51a8951ce576ccd4430e09c9c8bcae Mon Sep 17 00:00:00 2001 From: Francesco Trotta Date: Wed, 9 Aug 2023 17:13:04 +0200 Subject: [PATCH] fix: do not report on shadowed constructors in `no-new-wrappers` (#17447) * fix: do not report on shadowed constructors in `no-new-wrappers` * unit tests for undefined constructors --- lib/rules/no-new-wrappers.js | 26 +++++++++++----- tests/lib/rules/no-new-wrappers.js | 49 +++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/lib/rules/no-new-wrappers.js b/lib/rules/no-new-wrappers.js index 9a12e1a3b5d..5050a98a044 100644 --- a/lib/rules/no-new-wrappers.js +++ b/lib/rules/no-new-wrappers.js @@ -5,6 +5,12 @@ "use strict"; +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { getVariableByName } = require("./utils/ast-utils"); + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -28,18 +34,24 @@ module.exports = { }, create(context) { + const { sourceCode } = context; return { NewExpression(node) { const wrapperObjects = ["String", "Number", "Boolean"]; - - if (wrapperObjects.includes(node.callee.name)) { - context.report({ - node, - messageId: "noConstructor", - data: { fn: node.callee.name } - }); + const { name } = node.callee; + + if (wrapperObjects.includes(name)) { + const variable = getVariableByName(sourceCode.getScope(node), name); + + if (variable && variable.identifiers.length === 0) { + context.report({ + node, + messageId: "noConstructor", + data: { fn: name } + }); + } } } }; diff --git a/tests/lib/rules/no-new-wrappers.js b/tests/lib/rules/no-new-wrappers.js index 57dba4e1285..0b5b686aef1 100644 --- a/tests/lib/rules/no-new-wrappers.js +++ b/tests/lib/rules/no-new-wrappers.js @@ -21,7 +21,36 @@ const ruleTester = new RuleTester(); ruleTester.run("no-new-wrappers", rule, { valid: [ "var a = new Object();", - "var a = String('test'), b = String.fromCharCode(32);" + "var a = String('test'), b = String.fromCharCode(32);", + ` + function test(Number) { + return new Number; + } + `, + { + code: ` + import String from "./string"; + const str = new String(42); + `, + parserOptions: { ecmaVersion: 6, sourceType: "module" } + }, + ` + if (foo) { + result = new Boolean(bar); + } else { + var Boolean = CustomBoolean; + } + `, + { + code: "new String()", + globals: { + String: "off" + } + }, + ` + /* global Boolean:off */ + assert(new Boolean); + ` ], invalid: [ { @@ -53,6 +82,24 @@ ruleTester.run("no-new-wrappers", rule, { }, type: "NewExpression" }] + }, + { + code: ` + const a = new String('bar'); + { + const String = CustomString; + const b = new String('foo'); + } + `, + parserOptions: { ecmaVersion: 6 }, + errors: [{ + messageId: "noConstructor", + data: { + fn: "String" + }, + type: "NewExpression", + line: 2 + }] } ] });