diff --git a/lib/rules/no-new-func.js b/lib/rules/no-new-func.js index d1360e9dee0..9af4e31cabf 100644 --- a/lib/rules/no-new-func.js +++ b/lib/rules/no-new-func.js @@ -29,26 +29,29 @@ module.exports = { create(context) { - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Reports a node. - * @param {ASTNode} node The node to report - * @returns {void} - * @private - */ - function report(node) { - context.report({ - node, - messageId: "noFunctionConstructor" - }); - } - return { - "NewExpression[callee.name = 'Function']": report, - "CallExpression[callee.name = 'Function']": report + "Program:exit"() { + const globalScope = context.getScope(); + const variable = globalScope.set.get("Function"); + + if (variable && variable.defs.length === 0) { + variable.references.forEach(ref => { + const node = ref.identifier; + const { parent } = node; + + if ( + parent && + (parent.type === "NewExpression" || parent.type === "CallExpression") && + node === parent.callee + ) { + context.report({ + node: parent, + messageId: "noFunctionConstructor" + }); + } + }); + } + } }; } diff --git a/tests/lib/rules/no-new-func.js b/tests/lib/rules/no-new-func.js index bcb35e343ec..aa0542090e2 100644 --- a/tests/lib/rules/no-new-func.js +++ b/tests/lib/rules/no-new-func.js @@ -21,7 +21,24 @@ const ruleTester = new RuleTester(); ruleTester.run("no-new-func", rule, { valid: [ "var a = new _function(\"b\", \"c\", \"return b+c\");", - "var a = _function(\"b\", \"c\", \"return b+c\");" + "var a = _function(\"b\", \"c\", \"return b+c\");", + { + code: "class Function {}; new Function()", + parserOptions: { + ecmaVersion: 2015 + } + }, + { + code: "const fn = () => { class Function {}; new Function() }", + parserOptions: { + ecmaVersion: 2015 + } + }, + "function Function() {}; Function()", + "var fn = function () { function Function() {}; Function() }", + "var x = function Function() { Function(); }", + "call(Function)", + "new Class(Function)" ], invalid: [ { @@ -37,6 +54,23 @@ ruleTester.run("no-new-func", rule, { messageId: "noFunctionConstructor", type: "CallExpression" }] + }, + { + code: "const fn = () => { class Function {} }; new Function('', '')", + parserOptions: { + ecmaVersion: 2015 + }, + errors: [{ + messageId: "noFunctionConstructor", + type: "NewExpression" + }] + }, + { + code: "var fn = function () { function Function() {} }; Function('', '')", + errors: [{ + messageId: "noFunctionConstructor", + type: "CallExpression" + }] } ] });