Skip to content

Commit 599668e

Browse files
authored
Merge pull request #441 from kylemh/master
Resolve issue with first displayName always being used
2 parents 0ffe1e1 + 191aad1 commit 599668e

File tree

4 files changed

+76
-1
lines changed

4 files changed

+76
-1
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as React from 'react';
2+
3+
interface ButtonProps
4+
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {}
5+
6+
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
7+
(props, ref) => <button {...props} ref={ref} type="button" />
8+
);
9+
10+
Button.displayName = 'First';
11+
12+
export const SubmitButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
13+
(props, ref) => <button {...props} ref={ref} type="submit" />
14+
);
15+
16+
SubmitButton.displayName = 'Second';
17+
18+
export const ResetButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
19+
(props, ref) => <button {...props} ref={ref} type="reset" />
20+
);
21+
22+
ResetButton.displayName = 'Third';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as React from 'react';
2+
3+
interface ButtonProps
4+
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {}
5+
6+
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
7+
(props, ref) => <button {...props} ref={ref} type="button" />
8+
);
9+
10+
Button.displayName = 'First';
11+
12+
export const someSeparateFunction = () => {};

src/__tests__/parser.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,32 @@ describe('parser', () => {
989989
const [parsed] = parse(fixturePath('StatefulDisplayNameFolder/index'));
990990
assert.equal(parsed.displayName, 'StatefulDisplayNameFolder');
991991
});
992+
993+
it('should get all displayNames from single file when multiple functions have the property defined', () => {
994+
const [parsed1, parsed2, parsed3] = parse(
995+
fixturePath('StatelessDisplayNameMultipleDisplayNames')
996+
);
997+
998+
// parsed1.displayName === 'Button'?
999+
// parsed1.displayName === 'SubmitButton'?
1000+
// parsed1.displayName === 'ResetButton'?
1001+
1002+
assert.equal(parsed1.displayName, 'First');
1003+
assert.equal(parsed2.displayName, 'Second');
1004+
assert.equal(parsed3.displayName, 'Third');
1005+
});
1006+
1007+
it('should get all displayNames from single file when multiple functions have the property defined', () => {
1008+
const [parsed1, parsed2] = parse(
1009+
fixturePath('StatelessDisplayNameMultipleFnsOneDisplayName')
1010+
);
1011+
1012+
// parsed1.displayName === 'Button'?
1013+
// parsed2 is `undefined`?
1014+
1015+
assert.equal(parsed1.displayName, 'First');
1016+
assert.equal(parsed2.displayName, 'someSeparateFunction');
1017+
});
9921018
});
9931019

9941020
describe('Parser options', () => {

src/parser.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1200,11 +1200,26 @@ function getTextValueOfFunctionProperty(
12001200
.filter(statement => {
12011201
const expr = (statement as ts.ExpressionStatement)
12021202
.expression as ts.BinaryExpression;
1203+
1204+
/**
1205+
* Ensure the .displayName is for the currently processing function.
1206+
*
1207+
* This avoids the following situations:
1208+
*
1209+
* - A file has multiple functions, one has `.displayName`, and all
1210+
* functions ends up with that same `.displayName` value.
1211+
*
1212+
* - A file has multiple functions, each with a different
1213+
* `.displayName`, but the first is applied to all of them.
1214+
*/
1215+
const flowNodeNameEscapedText = (statement as any)?.flowNode?.node?.name
1216+
?.escapedText as false | ts.__String | undefined;
1217+
12031218
return (
12041219
expr.left &&
12051220
(expr.left as ts.PropertyAccessExpression).name &&
12061221
(expr.left as ts.PropertyAccessExpression).name.escapedText ===
1207-
propertyName
1222+
(propertyName && flowNodeNameEscapedText === exp.escapedName)
12081223
);
12091224
})
12101225
.filter(statement => {

0 commit comments

Comments
 (0)