From 5b9ee47f596cd516d6204adeac0e03a8bf9cb8b1 Mon Sep 17 00:00:00 2001 From: Oriol Puig Date: Wed, 24 Jul 2024 14:40:16 +0200 Subject: [PATCH] feat(packages/eslint-plugin-sui): Make decorator-deprecated-remark-method runs on classes --- .../decorator-deprecated-remark-method.js | 113 ++++++++++++++---- packages/sui-lint/eslintrc.js | 4 +- 2 files changed, 96 insertions(+), 21 deletions(-) diff --git a/packages/eslint-plugin-sui/src/rules/decorator-deprecated-remark-method.js b/packages/eslint-plugin-sui/src/rules/decorator-deprecated-remark-method.js index 5c47a7e90..1cbe14101 100644 --- a/packages/eslint-plugin-sui/src/rules/decorator-deprecated-remark-method.js +++ b/packages/eslint-plugin-sui/src/rules/decorator-deprecated-remark-method.js @@ -3,10 +3,72 @@ */ 'use strict' +const dedent = require('string-dedent') + // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ +function getElementName(node, {isAClass, isAMethod, isArrowFunction}) { + if (isAClass) { + const className = node.id?.name ?? 'UnknownClass' + return `class ${className}` + } + + if (isArrowFunction) { + const methodNode = node.parent + const classNode = methodNode?.parent?.parent + const className = classNode.id?.name ?? 'UnknownClass' + const methodName = methodNode.key?.name ?? 'UnknownMethod' + + return `method ${className}.${methodName}` + } + + if (isAMethod) { + const classNode = node.parent?.parent + const className = classNode.id?.name ?? 'UnknownClass' + const methodName = node.key?.name ?? 'UnknownMethod' + + return `method ${className}.${methodName}` + } + + return 'unknown' +} + +function getDecoratorsNode(node, {isAClass, isAMethod, isArrowFunction}) { + if (isAClass) { + return node.decorators + } + + if (isArrowFunction) { + const methodNode = node.parent + return methodNode.decorators ?? [] + } + + if (isAMethod) { + return node.decorators ?? [] + } + + return [] +} + +function remarkElement(node, {isAClass, isAMethod, isArrowFunction}) { + if (isAClass) { + return node.id + } + + if (isArrowFunction) { + const methodNode = node.parent + return methodNode.key + } + + if (isAMethod) { + return node.key + } + + return node +} + /** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { @@ -18,34 +80,45 @@ module.exports = { }, fixable: 'code', schema: [], - messages: {} + messages: { + remarkWarningMessage: dedent` + The {{methodName}} is marked as a deprecated. + ` + } }, create: function (context) { - // TODO: Check using decorator in a Class. + function highlightNode(node) { + const isAClass = node.type === 'ClassDeclaration' + const isArrowFunction = node.type === 'ArrowFunctionExpression' + const isAMethod = node.type === 'MethodDefinition' - return { - MethodDefinition(node) { - // Method - const method = node + const nodeName = getElementName(node, {isAClass, isAMethod, isArrowFunction}) + const decorators = getDecoratorsNode(node, {isAClass, isAMethod, isArrowFunction}) + const hasDecorators = decorators?.length > 0 - // Method decorators - const methodDecorators = method.decorators - const hasDecorators = methodDecorators?.length > 0 + // Get the @Deprecated() decorator from node decorators + const deprecatedDecoratorNode = + hasDecorators && decorators?.find(decorator => decorator?.expression?.callee?.name === 'Deprecated') - if (!hasDecorators) return + if (!deprecatedDecoratorNode) return + console.log(nodeName, deprecatedDecoratorNode) - // Get the @Deprecated() decorator from method - const deprecatedDecoratorNode = - hasDecorators && methodDecorators?.find(decorator => decorator?.expression?.callee?.name === 'Deprecated') + const nodeToRemark = remarkElement(node, {isAClass, isAMethod, isArrowFunction}) - if (!deprecatedDecoratorNode) return + // RULE: Mark method with a warning + context.report({ + node: nodeToRemark, + messageId: 'remarkWarningMessage', + data: { + methodName: nodeName + } + }) + } - // RULE: Mark method with a warning - context.report({ - node: method.key, - message: 'This method is marked as a deprecated.' - }) - } + return { + ClassDeclaration: highlightNode, + ArrowFunctionExpression: highlightNode, + MethodDefinition: highlightNode } } } diff --git a/packages/sui-lint/eslintrc.js b/packages/sui-lint/eslintrc.js index 06787f9b6..6e7cc3c9a 100644 --- a/packages/sui-lint/eslintrc.js +++ b/packages/sui-lint/eslintrc.js @@ -239,7 +239,9 @@ module.exports = { rules: { 'sui/factory-pattern': RULES.WARNING, 'sui/serialize-deserialize': RULES.WARNING, - 'sui/decorators': RULES.WARNING + 'sui/decorators': RULES.WARNING, + 'sui/decorator-deprecated': RULES.ERROR, + 'sui/decorator-deprecated-remark-method': RULES.WARNING } }, {