From 4326b0349d390bf4869351d1cefa5df2f1208ea1 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Tue, 13 Feb 2024 16:01:09 +0100 Subject: [PATCH] Fix nested classes case in `no-ember-super-in-es-classes` (#2071) * A failing test for no-ember-super-in-es-classes This rule incorrectly fails on the following code: ```js class Foo { bar() { Baz.reopen({ quux() { this._super(); }, }); } } ``` * Add a fix proposal * boolean instead * lint * fixup --- lib/rules/no-ember-super-in-es-classes.js | 25 +++++++++++++++++++ .../lib/rules/no-ember-super-in-es-classes.js | 17 +++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lib/rules/no-ember-super-in-es-classes.js b/lib/rules/no-ember-super-in-es-classes.js index efcf5c352c..93ffff18a5 100644 --- a/lib/rules/no-ember-super-in-es-classes.js +++ b/lib/rules/no-ember-super-in-es-classes.js @@ -1,5 +1,26 @@ 'use strict'; +function isDirectlyInClass(node) { + let currentNode = node.parent; + let inFunctionAlready = false; + + while (currentNode) { + if (currentNode.type === 'MethodDefinition') { + return true; + } else if (currentNode.type === 'FunctionExpression') { + if (inFunctionAlready) { + return false; + } else { + inFunctionAlready = true; + } + } + + currentNode = currentNode.parent; + } + + return false; +} + /** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { @@ -19,6 +40,10 @@ module.exports = { 'MethodDefinition MemberExpression[object.type="ThisExpression"][property.name="_super"]'( node ) { + if (!isDirectlyInClass(node)) { + return; + } + context.report({ node, message: "Don't use `this._super` in ES classes; instead, you should use `super`", diff --git a/tests/lib/rules/no-ember-super-in-es-classes.js b/tests/lib/rules/no-ember-super-in-es-classes.js index 0a016a38f4..ddb884f158 100644 --- a/tests/lib/rules/no-ember-super-in-es-classes.js +++ b/tests/lib/rules/no-ember-super-in-es-classes.js @@ -18,6 +18,9 @@ eslintTester.run('no-ember-super-in-es-classes', rule, { 'EmberObject.extend({ init() { this._super(); } })', 'EmberObject.extend({ init(a, b) { this._super(a, b); } })', 'EmberObject.extend({ init() { this._super(...arguments); } })', + 'class Foo { bar() { Baz.reopen({ quux() { this._super(); } }); } }', + 'class Foo { bar() { return function() { this._super(); }; } }', + 'class Foo { bar() { return { baz() { this._super() } }; } }', ], invalid: [ { @@ -70,5 +73,19 @@ eslintTester.run('no-ember-super-in-es-classes', rule, { { message: "Don't use `this._super` in ES classes; instead, you should use `super`" }, ], }, + { + code: 'class Foo { init() { return { a: this._super() }; } }', + output: 'class Foo { init() { return { a: super.init() }; } }', + errors: [ + { message: "Don't use `this._super` in ES classes; instead, you should use `super`" }, + ], + }, + { + code: 'class Foo { init() { return () => { this._super(); }; } }', + output: 'class Foo { init() { return () => { super.init(); }; } }', + errors: [ + { message: "Don't use `this._super` in ES classes; instead, you should use `super`" }, + ], + }, ], });