Skip to content

Commit

Permalink
fix(codemods): Fix bug with extra parentheses
Browse files Browse the repository at this point in the history
- codemods were adding extra parentheses to the
code when there was return statement
  • Loading branch information
pavelklibani committed Oct 23, 2024
1 parent dee02f6 commit 99e5996
Show file tree
Hide file tree
Showing 15 changed files with 88 additions and 23 deletions.
3 changes: 2 additions & 1 deletion packages/codemods/src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -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 };
49 changes: 49 additions & 0 deletions packages/codemods/src/helpers/removeCircleBrackets.ts
Original file line number Diff line number Diff line change
@@ -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<RegExpMatchArray> = 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;
};
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => (
<>
<Link />
<Link isUnderlined />
<Link isUnderlined={true} />
<Link isUnderlined={false} />
</>
);
export const MyComponent = () => {
return (
<div>
<Link />
<Link isUnderlined />
<Link isUnderlined={true} />
<Link isUnderlined={false} />
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => (
<>
<Link />
<Link underlined="always" />
<Link underlined="always" />
<Link />
</>
);
export const MyComponent = () => {
return (
<div>
<Link />
<Link underlined="always" />
<Link underlined="always" />
<Link />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { API, FileInfo } from 'jscodeshift';
import { removeCircleBrackets } from '../../../helpers';

const transform = (fileInfo: FileInfo, api: API) => {
const j = api.jscodeshift;
Expand Down Expand Up @@ -44,7 +45,7 @@ const transform = (fileInfo: FileInfo, api: API) => {
}
}

return root.toSource();
return removeCircleBrackets(root.toSource());
};

export default transform;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { API, FileInfo } from 'jscodeshift';
import { removeCircleBrackets } from '../../../helpers';

const transform = (fileInfo: FileInfo, api: API) => {
const j = api.jscodeshift;
Expand Down Expand Up @@ -44,7 +45,7 @@ const transform = (fileInfo: FileInfo, api: API) => {
}
}

return root.toSource();
return removeCircleBrackets(root.toSource());
};

export default transform;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { API, FileInfo } from 'jscodeshift';
import { removeCircleBrackets } from '../../../helpers';

const transform = (fileInfo: FileInfo, api: API) => {
const j = api.jscodeshift;
Expand Down Expand Up @@ -43,7 +44,7 @@ const transform = (fileInfo: FileInfo, api: API) => {
}
}

return root.toSource();
return removeCircleBrackets(root.toSource());
};

export default transform;
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -61,7 +62,7 @@ const transform = (fileInfo: FileInfo, api: API): string => {
});
}

return root.toSource();
return removeCircleBrackets(root.toSource());
};

export default transform;
5 changes: 3 additions & 2 deletions packages/codemods/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -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__/**"]
}

0 comments on commit 99e5996

Please sign in to comment.