From 77f43f0a996783c09c4f3d61d7e17b99aaf1447a Mon Sep 17 00:00:00 2001 From: Pavel Klibani Date: Wed, 23 Oct 2024 21:19:52 +0200 Subject: [PATCH] Fix(codemods): Fix bug with extra parentheses - codemods were adding extra parentheses to the code when there was return statement --- packages/codemods/src/helpers/index.ts | 3 +- .../src/helpers/removeCircleBrackets.ts | 49 +++++++++++++++++++ .../button-isSquare-prop-name.input.tsx | 1 + .../button-isSquare-prop-name.output.tsx | 1 + .../buttonLink-isSquare-prop-name.input.tsx | 1 + .../buttonLink-isSquare-prop-name.output.tsx | 1 + .../heading-elementType-prop.input.tsx | 1 + .../heading-elementType-prop.output.tsx | 1 + .../link-underlined-prop.input.tsx | 18 ++++--- .../link-underlined-prop.output.tsx | 18 ++++--- .../v3/web-react/button-isSquare-prop-name.ts | 3 +- .../buttonLink-isSquare-prop-name.ts | 3 +- .../v3/web-react/heading-elementType-prop.ts | 3 +- .../v3/web-react/link-underlined-prop.ts | 3 +- packages/codemods/tsconfig.json | 5 +- 15 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 packages/codemods/src/helpers/removeCircleBrackets.ts diff --git a/packages/codemods/src/helpers/index.ts b/packages/codemods/src/helpers/index.ts index 9f7bc11221..4250f2d021 100644 --- a/packages/codemods/src/helpers/index.ts +++ b/packages/codemods/src/helpers/index.ts @@ -1,4 +1,5 @@ import { errorMessage, infoMessage, logMessage } from './message'; import { _dirname } from './path'; +import { removeCircleBrackets } from './removeCircleBrackets'; -export { _dirname, errorMessage, infoMessage, logMessage }; +export { _dirname, errorMessage, infoMessage, logMessage, removeCircleBrackets }; diff --git a/packages/codemods/src/helpers/removeCircleBrackets.ts b/packages/codemods/src/helpers/removeCircleBrackets.ts new file mode 100644 index 0000000000..c941385986 --- /dev/null +++ b/packages/codemods/src/helpers/removeCircleBrackets.ts @@ -0,0 +1,49 @@ +// This function removes circle brackets from the return statement in the JSX component. +// This bug is introduced by 'recast library' which is used by 'jscodeshift' library. +// There is pull request to fix this issue: https://github.com/benjamn/recast/pull/1406, but it is not merged yet. +// @see https://github.com/facebook/jscodeshift/issues/534 +// @todo Can be removed when the issue is fixed in the 'recast' library. + +const REG_RETURN = /return\s+\((\s+)\(<([^\s>]+)/g; + +export const removeCircleBrackets = (string: string): string => { + const matches: IterableIterator = string.matchAll(REG_RETURN); + let result = ''; + + const allMatches = [...matches]; + if (allMatches.length === 0) return string; + + allMatches.forEach((match) => { + const [, spaces, componentName] = match; + const sl: number = spaces.length; + + const REG_DOUBLE_TAG = `(return\\s+\\(\\s{${sl}})\\((<${componentName}.+?\\s{${sl}}<\\/${componentName}>)\\)(\\s+\\))`; + const REG_SELF_CLOSING = `(return\\s+\\(\\s{${sl}})\\((<${componentName}.+?\\/>)\\)(\\s+\\))`; + const regexp = new RegExp(`${REG_DOUBLE_TAG}|${REG_SELF_CLOSING}`, 'gs'); + + result = string.replace( + regexp, + ( + match: string, // eslint-disable-line + doubleTagStart?: string, + doubleTagContent?: string, + doubleTagEnd?: string, + selfTagStart?: string, + selfTagContent?: string, + selfTagEnd?: string, + ): string => { + if (doubleTagStart && doubleTagContent && doubleTagEnd) { + return doubleTagStart + doubleTagContent + doubleTagEnd; + } + + if (selfTagStart && selfTagContent && selfTagEnd) { + return selfTagStart + selfTagContent + selfTagEnd; + } + + return match; + }, + ); + }); + + return result; +}; diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/button-isSquare-prop-name.input.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/button-isSquare-prop-name.input.tsx index 865de759f6..42d31866b1 100644 --- a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/button-isSquare-prop-name.input.tsx +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/button-isSquare-prop-name.input.tsx @@ -1,3 +1,4 @@ +import React from 'react'; // @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. import { Button } from '@lmc-eu/spirit-web-react'; diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/button-isSquare-prop-name.output.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/button-isSquare-prop-name.output.tsx index 17bed9b9b9..3f7cd9cae5 100644 --- a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/button-isSquare-prop-name.output.tsx +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/button-isSquare-prop-name.output.tsx @@ -1,3 +1,4 @@ +import React from 'react'; // @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. import { Button } from '@lmc-eu/spirit-web-react'; diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/buttonLink-isSquare-prop-name.input.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/buttonLink-isSquare-prop-name.input.tsx index faa8f68394..f3c5c5296b 100644 --- a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/buttonLink-isSquare-prop-name.input.tsx +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/buttonLink-isSquare-prop-name.input.tsx @@ -1,3 +1,4 @@ +import React from 'react'; // @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. import { ButtonLink } from '@lmc-eu/spirit-web-react'; diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/buttonLink-isSquare-prop-name.output.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/buttonLink-isSquare-prop-name.output.tsx index 2ab1b2d51d..fd6a131c0f 100644 --- a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/buttonLink-isSquare-prop-name.output.tsx +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/buttonLink-isSquare-prop-name.output.tsx @@ -1,3 +1,4 @@ +import React from 'react'; // @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. import { ButtonLink } from '@lmc-eu/spirit-web-react'; diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/heading-elementType-prop.input.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/heading-elementType-prop.input.tsx index 77d8fee5c7..48b4374a51 100644 --- a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/heading-elementType-prop.input.tsx +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/heading-elementType-prop.input.tsx @@ -1,3 +1,4 @@ +import React from 'react'; // @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. import { Heading } from '@lmc-eu/spirit-web-react'; diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/heading-elementType-prop.output.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/heading-elementType-prop.output.tsx index 9b03b15a4c..3da426f4bf 100644 --- a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/heading-elementType-prop.output.tsx +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/heading-elementType-prop.output.tsx @@ -1,3 +1,4 @@ +import React from 'react'; // @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. import { Heading } from '@lmc-eu/spirit-web-react'; diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.input.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.input.tsx index 90af8e3291..a2fc3cd974 100644 --- a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.input.tsx +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.input.tsx @@ -2,11 +2,13 @@ import React from 'react'; // @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. import { Link } from '@lmc-eu/spirit-web-react'; -export const MyComponent = () => ( - <> - - - - - -); +export const MyComponent = () => { + return ( +
+ + + + +
+ ); +}; diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.output.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.output.tsx index 35c1fbb249..3ae1ad5821 100644 --- a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.output.tsx +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.output.tsx @@ -2,11 +2,13 @@ import React from 'react'; // @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. import { Link } from '@lmc-eu/spirit-web-react'; -export const MyComponent = () => ( - <> - - - - - -); +export const MyComponent = () => { + return ( +
+ + + + +
+ ); +}; diff --git a/packages/codemods/src/transforms/v3/web-react/button-isSquare-prop-name.ts b/packages/codemods/src/transforms/v3/web-react/button-isSquare-prop-name.ts index 8cc5de70f0..65edc53bf2 100644 --- a/packages/codemods/src/transforms/v3/web-react/button-isSquare-prop-name.ts +++ b/packages/codemods/src/transforms/v3/web-react/button-isSquare-prop-name.ts @@ -1,4 +1,5 @@ import { API, FileInfo } from 'jscodeshift'; +import { removeCircleBrackets } from '../../../helpers'; const transform = (fileInfo: FileInfo, api: API) => { const j = api.jscodeshift; @@ -44,7 +45,7 @@ const transform = (fileInfo: FileInfo, api: API) => { } } - return root.toSource(); + return removeCircleBrackets(root.toSource()); }; export default transform; diff --git a/packages/codemods/src/transforms/v3/web-react/buttonLink-isSquare-prop-name.ts b/packages/codemods/src/transforms/v3/web-react/buttonLink-isSquare-prop-name.ts index 0f5da0116c..8fdbd6a727 100644 --- a/packages/codemods/src/transforms/v3/web-react/buttonLink-isSquare-prop-name.ts +++ b/packages/codemods/src/transforms/v3/web-react/buttonLink-isSquare-prop-name.ts @@ -1,4 +1,5 @@ import { API, FileInfo } from 'jscodeshift'; +import { removeCircleBrackets } from '../../../helpers'; const transform = (fileInfo: FileInfo, api: API) => { const j = api.jscodeshift; @@ -44,7 +45,7 @@ const transform = (fileInfo: FileInfo, api: API) => { } } - return root.toSource(); + return removeCircleBrackets(root.toSource()); }; export default transform; diff --git a/packages/codemods/src/transforms/v3/web-react/heading-elementType-prop.ts b/packages/codemods/src/transforms/v3/web-react/heading-elementType-prop.ts index 1f6d8a65f6..1f9293c98a 100644 --- a/packages/codemods/src/transforms/v3/web-react/heading-elementType-prop.ts +++ b/packages/codemods/src/transforms/v3/web-react/heading-elementType-prop.ts @@ -1,4 +1,5 @@ import { API, FileInfo } from 'jscodeshift'; +import { removeCircleBrackets } from '../../../helpers'; const transform = (fileInfo: FileInfo, api: API) => { const j = api.jscodeshift; @@ -43,7 +44,7 @@ const transform = (fileInfo: FileInfo, api: API) => { } } - return root.toSource(); + return removeCircleBrackets(root.toSource()); }; export default transform; diff --git a/packages/codemods/src/transforms/v3/web-react/link-underlined-prop.ts b/packages/codemods/src/transforms/v3/web-react/link-underlined-prop.ts index 608fced2e3..57e95e6144 100644 --- a/packages/codemods/src/transforms/v3/web-react/link-underlined-prop.ts +++ b/packages/codemods/src/transforms/v3/web-react/link-underlined-prop.ts @@ -8,6 +8,7 @@ import { ImportDeclaration, JSXOpeningElement, } from 'jscodeshift'; +import { removeCircleBrackets } from '../../../helpers'; const transform = (fileInfo: FileInfo, api: API): string => { const j: JSCodeshift = api.jscodeshift; @@ -61,7 +62,7 @@ const transform = (fileInfo: FileInfo, api: API): string => { }); } - return root.toSource(); + return removeCircleBrackets(root.toSource()); }; export default transform; diff --git a/packages/codemods/tsconfig.json b/packages/codemods/tsconfig.json index 893379463b..2faa1cec55 100644 --- a/packages/codemods/tsconfig.json +++ b/packages/codemods/tsconfig.json @@ -25,8 +25,9 @@ "skipLibCheck": true, "typeRoots": ["../../node_modules/@types"], "types": ["node", "jest"], - "module": "es2020" + "module": "es2020", + "target": "es2020" }, - "include": ["./", "./.eslintrc.js"], + "include": ["./src/**/*"], "exclude": ["./node_modules", "**/__testfixtures__/**"] }