Skip to content

Commit ed25da9

Browse files
committed
Added support for renaming jsx props
Fixes #34
1 parent 08b8489 commit ed25da9

File tree

6 files changed

+61
-1
lines changed

6 files changed

+61
-1
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"@types/chai": "~4.3.3",
3333
"@types/mocha": "~10.0.0",
3434
"@types/node": "~14.18.26",
35+
"@types/react": "^19.0.10",
3536
"@typescript-eslint/eslint-plugin": "~5.40.1",
3637
"@typescript-eslint/parser": "~5.40.1",
3738
"chai": "~4.3.6",

src/transformer.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ function createTransformerFactory(program: ts.Program, options?: Partial<RenameO
139139
return handleBindingElement(node);
140140
}
141141

142+
// <Comp node={...} />
143+
if (ts.isJsxAttribute(node.parent) && node.parent.name === node) {
144+
return handleJsxAttributeName(node);
145+
}
146+
142147
// constructor(public node: string) { // <--- this
143148
// console.log(node); // <--- and this
144149
// }
@@ -207,6 +212,11 @@ function createTransformerFactory(program: ts.Program, options?: Partial<RenameO
207212
return createNewIdentifier(node);
208213
}
209214

215+
// <Comp node={...} />
216+
function handleJsxAttributeName(node: ts.Identifier): ts.Identifier {
217+
return createNewIdentifier(node);
218+
}
219+
210220
// const a = { node: 123 }
211221
function handlePropertyAssignment(node: ts.Identifier): ts.Identifier {
212222
return createNewIdentifier(node);
@@ -425,6 +435,17 @@ function createTransformerFactory(program: ts.Program, options?: Partial<RenameO
425435
return VisibilityType.External;
426436
}
427437

438+
// <Comp node={...} />
439+
if (ts.isJsxAttribute(node.parent)) {
440+
const jsxTagSymbol = typeChecker.getSymbolAtLocation(node.parent.parent.parent.tagName);
441+
if (jsxTagSymbol !== undefined && jsxTagSymbol.valueDeclaration !== undefined) {
442+
const jsxPropsType = typeChecker.getTypeOfSymbolAtLocation(jsxTagSymbol, jsxTagSymbol.valueDeclaration);
443+
if (isTypePropertyExternal(jsxPropsType, node.getText())) {
444+
return VisibilityType.External;
445+
}
446+
}
447+
}
448+
428449
const nodeSymbol = getNodeSymbol(node);
429450
const classOfMember = nodeSymbol !== null ? getClassOfMemberSymbol(nodeSymbol) : null;
430451
if (classOfMember !== null && isTypePropertyExternal(typeChecker.getTypeAtLocation(classOfMember), node.getText())) {

tests/functional-test-cases.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ function prepareString(str: string): string {
2626
return str.trim().replace(/\r\n/g, '\n');
2727
}
2828

29+
function findInputFile(testCaseDir: string): string {
30+
const tsFilePath = path.join(testCaseDir, 'input.ts');
31+
if (fs.existsSync(tsFilePath)) {
32+
return tsFilePath;
33+
}
34+
35+
const tsxFilePath = path.join(testCaseDir, 'input.tsx');
36+
if (fs.existsSync(tsxFilePath)) {
37+
return tsxFilePath;
38+
}
39+
40+
throw new Error(`Cannot find input file in ${testCaseDir}`);
41+
}
42+
2943
function getTestCases(): TestCase[] {
3044
if (!fs.existsSync(testCasesDir) || !fs.lstatSync(testCasesDir).isDirectory()) {
3145
throw new Error(`${testCasesDir} folder does not exist`);
@@ -38,7 +52,7 @@ function getTestCases(): TestCase[] {
3852
.map((directoryName: string) => {
3953
const testCaseDir = path.resolve(testCasesDir, directoryName);
4054
const outputFileName = path.resolve(testCaseDir, 'output.js');
41-
const inputFileName = path.relative(process.cwd(), path.resolve(testCaseDir, 'input.ts'));
55+
const inputFileName = path.relative(process.cwd(), findInputFile(testCaseDir));
4256

4357
assert(fs.existsSync(inputFileName), `Input file doesn't exist for ${directoryName}`);
4458
assert(fs.existsSync(outputFileName), `Output file doesn't exist for ${directoryName}`);

tests/test-cases/tsx/input.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import React from "react";
2+
3+
interface SkeletonProps {
4+
history: History;
5+
}
6+
7+
const Skeleton = ({ history }: SkeletonProps) => (
8+
<div className={String(history.length)} />
9+
);
10+
11+
const AppImpl = () => (
12+
<Skeleton history={history} />
13+
);

tests/test-cases/tsx/output.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import React from "react";
2+
const Skeleton = ({ _internal_history: history }) => (React.createElement("div", { className: String(history.length) }));
3+
const AppImpl = () => (React.createElement(Skeleton, { _internal_history: history }));

tests/test-cases/tsx/tsconfig.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"compilerOptions": {
3+
"jsx": "react",
4+
"target": "ES2015",
5+
"moduleResolution": "node",
6+
"esModuleInterop": true
7+
}
8+
}

0 commit comments

Comments
 (0)