From 6f363cf2d3c88cb7ac4ac1bce8f8e218cb96b651 Mon Sep 17 00:00:00 2001 From: Arthur Geron Date: Tue, 31 Oct 2023 00:45:34 -0300 Subject: [PATCH] fix: name generation conflict resolution would create variables with the same name "renameMe" --- __tests__/require-usememo.test.ts | 52 +++++++++++++++++++++++++++++++ package.json | 6 +++- src/require-usememo/constants.ts | 1 + src/require-usememo/utils.ts | 15 +++++---- yarn.lock | 10 ++++++ 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/__tests__/require-usememo.test.ts b/__tests__/require-usememo.test.ts index 1d6c5c3..0bc3b42 100644 --- a/__tests__/require-usememo.test.ts +++ b/__tests__/require-usememo.test.ts @@ -481,11 +481,63 @@ describe('Rule - Require-usememo', () => { const Component = () => { const userData = undefined; const _userData = undefined; + const __userData = useMemo(() => ({}), []); + return ; + }`, + errors: [{ messageId: "object-usememo-props" }], + }, + { + code: ` + const Component = () => { + const userData = undefined; + const _userData = undefined; + const __userData = undefined; + const ___userData = undefined; + const ____userData = undefined; + const _____userData = undefined; + return ; + }`, + output: `import { useMemo } from 'react'; + + const Component = () => { + const userData = undefined; + const _userData = undefined; + const __userData = undefined; + const ___userData = undefined; + const ____userData = undefined; + const _____userData = undefined; const renameMe = useMemo(() => ({}), []); return ; }`, errors: [{ messageId: "object-usememo-props" }], }, + { + code: ` + const Component = () => { + const userData = undefined; + const _userData = undefined; + const __userData = undefined; + const ___userData = undefined; + const ____userData = undefined; + const _____userData = undefined; + const renameMe = undefined; + return ; + }`, + output: `import { useMemo } from 'react'; + + const Component = () => { + const userData = undefined; + const _userData = undefined; + const __userData = undefined; + const ___userData = undefined; + const ____userData = undefined; + const _____userData = undefined; + const renameMe = undefined; + const renameMe_99c32a94 = useMemo(() => ({}), []); + return ; + }`, + errors: [{ messageId: "object-usememo-props" }], + }, { code: ` const Component = () => { diff --git a/package.json b/package.json index 75e7f34..97d0687 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@rollup/plugin-typescript": "8.3.3", "@types/eslint": "8.4.5", "@types/jest": "28.1.5", + "@types/uuid": "9.0.6", "@typescript-eslint/parser": "5.30.6", "@typescript-eslint/types": "5.30.6", "eslint": "8.19.0", @@ -37,5 +38,8 @@ }, "files": [ "dist" - ] + ], + "dependencies": { + "uuid": "9.0.1" + } } diff --git a/src/require-usememo/constants.ts b/src/require-usememo/constants.ts index 729311f..68f6915 100644 --- a/src/require-usememo/constants.ts +++ b/src/require-usememo/constants.ts @@ -1,6 +1,7 @@ import { MemoStatus } from 'src/types'; import type { ExpressionData, MemoErrorHookDictionary } from './types'; +export const nameGeneratorUUID = 'b32a4d70-4f64-11eb-89d5-33e6ce8a6c99'; export const jsxEmptyExpressionClassData: ExpressionData = { [MemoStatus.UnmemoizedObject.toString()]: "object-class-memo-props", [MemoStatus.UnmemoizedArray.toString()]: "array-class-memo-props", diff --git a/src/require-usememo/utils.ts b/src/require-usememo/utils.ts index 3f84da5..0fbe270 100644 --- a/src/require-usememo/utils.ts +++ b/src/require-usememo/utils.ts @@ -4,9 +4,9 @@ import type * as ESTree from "estree"; import { MessagesRequireUseMemo } from '../constants'; import type { ESNode, ExpressionData, ReactImportInformation } from "./types"; import { MemoStatusToReport } from "src/types"; -import { messageIdToHookDict } from "./constants"; +import { messageIdToHookDict, nameGeneratorUUID } from "./constants"; import { getVariableInScope } from "src/common"; - +import { v5 as uuidV5 } from 'uuid'; export function shouldIgnoreNode(node: ESNode, ignoredNames: Record ) { return !!ignoredNames[(node as TSESTree.Node as TSESTree.Identifier)?.name] @@ -116,15 +116,18 @@ function fixFunction(node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpre return fixedCode; } -function getSafeVariableName(context: Rule.RuleContext, name: string) { +function getSafeVariableName(context: Rule.RuleContext, name:string, attempts = 0): string { const tempVarPlaceholder = 'renameMe'; + if (!getVariableInScope(context, name)) { return name; } - if (!getVariableInScope(context, `_${name}`)) { - return `_${name}`; + if (attempts >= 5) { + const nameExtensionIfExists = getVariableInScope(context, tempVarPlaceholder) ? uuidV5(name, nameGeneratorUUID).split('-')[0] : ''; + return `${tempVarPlaceholder}${nameExtensionIfExists ? `_${nameExtensionIfExists}` : ''}`; } - return tempVarPlaceholder; + return getSafeVariableName(context, `_${name}`, ++attempts); + } // Eslint Auto-fix logic, functional components/hooks only diff --git a/yarn.lock b/yarn.lock index 1ff57ae..39dbe44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -974,6 +974,11 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.2.tgz#01284dde9ef4e6d8cef6422798d9a3ad18a66f8b" integrity sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw== +"@types/uuid@9.0.6": + version "9.0.6" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.6.tgz#c91ae743d8344a54b2b0c691195f5ff5265f6dfb" + integrity sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew== + "@types/yargs-parser@*": version "21.0.2" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b" @@ -3533,6 +3538,11 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +uuid@9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"