From 291f88a9bbbfc1f6c824872da786d6958135f176 Mon Sep 17 00:00:00 2001 From: Markus Sanin Date: Tue, 4 Jun 2024 14:27:46 +0200 Subject: [PATCH 1/5] Fix false positive error in `no-runloop` validator --- lib/rules/no-runloop.js | 2 +- tests/lib/rules/no-runloop.js | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/rules/no-runloop.js b/lib/rules/no-runloop.js index 84de1db172..a09d2efdee 100644 --- a/lib/rules/no-runloop.js +++ b/lib/rules/no-runloop.js @@ -119,7 +119,7 @@ module.exports = { if (node.callee.type === 'Identifier') { const name = node.callee.name; const runloopFn = localToImportedNameMap[name]; - const isNotAllowed = runloopFn && !allowList.includes(runloopFn); + const isNotAllowed = runloopFn && !allowList.includes(runloopFn) && !Object.prototype.hasOwnProperty.call(Object.prototype, name); if (isNotAllowed) { report(node, runloopFn, name); } diff --git a/tests/lib/rules/no-runloop.js b/tests/lib/rules/no-runloop.js index e7d75c3c63..e14bbb33a2 100644 --- a/tests/lib/rules/no-runloop.js +++ b/tests/lib/rules/no-runloop.js @@ -65,6 +65,28 @@ eslintTester.run('no-runloop', rule, { `, options: [{ allowList: ['later'] }], }, + ` + function hasOwnProperty() {}; + hasOwnProperty(); + + function isPrototypeOf() {}; + isPrototypeOf(); + + function propertyIsEnumerable() {}; + propertyIsEnumerable(); + + function toLocaleString() {}; + toLocaleString(); + + function toString() {}; + toString(); + + function valueOf() {}; + valueOf(); + + function constructor() {}; + constructor(); + `, ], invalid: [ { From c36d34ef43729199932354c3f42be450c40a9034 Mon Sep 17 00:00:00 2001 From: Markus Sanin Date: Tue, 4 Jun 2024 14:36:28 +0200 Subject: [PATCH 2/5] Fix lint --- lib/rules/no-runloop.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/rules/no-runloop.js b/lib/rules/no-runloop.js index a09d2efdee..96c8d283f9 100644 --- a/lib/rules/no-runloop.js +++ b/lib/rules/no-runloop.js @@ -119,7 +119,10 @@ module.exports = { if (node.callee.type === 'Identifier') { const name = node.callee.name; const runloopFn = localToImportedNameMap[name]; - const isNotAllowed = runloopFn && !allowList.includes(runloopFn) && !Object.prototype.hasOwnProperty.call(Object.prototype, name); + const isNotAllowed = + runloopFn && + !allowList.includes(runloopFn) && + !Object.prototype.hasOwnProperty(name); if (isNotAllowed) { report(node, runloopFn, name); } From 724593a8e605aafc33275a4940dc77f2cf08e786 Mon Sep 17 00:00:00 2001 From: Markus Sanin Date: Tue, 4 Jun 2024 14:38:49 +0200 Subject: [PATCH 3/5] Fix lint --- lib/rules/no-runloop.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/rules/no-runloop.js b/lib/rules/no-runloop.js index 96c8d283f9..f0fd1ef7b7 100644 --- a/lib/rules/no-runloop.js +++ b/lib/rules/no-runloop.js @@ -120,9 +120,7 @@ module.exports = { const name = node.callee.name; const runloopFn = localToImportedNameMap[name]; const isNotAllowed = - runloopFn && - !allowList.includes(runloopFn) && - !Object.prototype.hasOwnProperty(name); + runloopFn && !allowList.includes(runloopFn) && !Object.prototype.hasOwnProperty(name); if (isNotAllowed) { report(node, runloopFn, name); } From bf4637b674454a69bb086ebec7ca1f0e942a146e Mon Sep 17 00:00:00 2001 From: Markus Sanin Date: Tue, 4 Jun 2024 14:44:43 +0200 Subject: [PATCH 4/5] Add test when functions were imported --- tests/lib/rules/no-runloop.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/lib/rules/no-runloop.js b/tests/lib/rules/no-runloop.js index e14bbb33a2..f20b12f5de 100644 --- a/tests/lib/rules/no-runloop.js +++ b/tests/lib/rules/no-runloop.js @@ -87,6 +87,17 @@ eslintTester.run('no-runloop', rule, { function constructor() {}; constructor(); `, + ` + import { hasOwnProperty, isPrototypeOf, propertyIsEnumerable, toLocaleString, toString, valueOf, constructor } from './util'; + + hasOwnProperty(); + isPrototypeOf(); + propertyIsEnumerable(); + toLocaleString(); + toString(); + valueOf(); + constructor(); + `, ], invalid: [ { From 0efc746b29eb38b7b918f22d826307d765e9242a Mon Sep 17 00:00:00 2001 From: Markus Sanin Date: Fri, 21 Jun 2024 14:22:01 +0200 Subject: [PATCH 5/5] use map instead of object --- lib/rules/no-runloop.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/rules/no-runloop.js b/lib/rules/no-runloop.js index f0fd1ef7b7..b889bf390d 100644 --- a/lib/rules/no-runloop.js +++ b/lib/rules/no-runloop.js @@ -75,7 +75,7 @@ module.exports = { // List of allowed runloop functions const allowList = context.options[0]?.allowList ?? []; // Maps local names to imported names of imports - const localToImportedNameMap = {}; + const localToImportedNameMap = new Map(); /** * Reports a node with usage of a disallowed runloop function @@ -107,7 +107,7 @@ module.exports = { if (spec.type === 'ImportSpecifier') { const importedName = spec.imported.name; if (EMBER_RUNLOOP_FUNCTIONS.includes(importedName)) { - localToImportedNameMap[spec.local.name] = importedName; + localToImportedNameMap.set(spec.local.name, importedName); } } } @@ -118,9 +118,8 @@ module.exports = { // Examples: run(...), later(...) if (node.callee.type === 'Identifier') { const name = node.callee.name; - const runloopFn = localToImportedNameMap[name]; - const isNotAllowed = - runloopFn && !allowList.includes(runloopFn) && !Object.prototype.hasOwnProperty(name); + const runloopFn = localToImportedNameMap.get(name); + const isNotAllowed = runloopFn && !allowList.includes(runloopFn); if (isNotAllowed) { report(node, runloopFn, name); } @@ -130,7 +129,7 @@ module.exports = { // Examples: run.later(...), run.schedule(...) if (node.callee.type === 'MemberExpression' && node.callee.object?.type === 'Identifier') { const objectName = node.callee.object.name; - const objectRunloopFn = localToImportedNameMap[objectName]; + const objectRunloopFn = localToImportedNameMap.get(objectName); if (objectRunloopFn === 'run' && node.callee.property?.type === 'Identifier') { const runloopFn = node.callee.property.name;