Skip to content

feat(linter): implement react/display-name rule#12084

Closed
taearls wants to merge 29 commits intooxc-project:mainfrom
taearls:linter/react-display-name
Closed

feat(linter): implement react/display-name rule#12084
taearls wants to merge 29 commits intooxc-project:mainfrom
taearls:linter/react-display-name

Conversation

@taearls
Copy link
Contributor

@taearls taearls commented Jul 4, 2025

I implemented the react/display-name rule. I categorized it as style because it's more idiomatic to add displayNames and helps with debugging, but it does not affect functionality and is not required for React to work.

In order to get all the tests to pass, I needed to add a version and a component_wrapper_functions setting to the react.rs module. This resulted in some snapshot updates.

All the options available for this rule are supported with this change. However, I commented out one specific test from the eslint-plugin-react test suite because when it's enabled, it throws an unexpected token error. It seems like their test suite is expecting Flow rather than TypeScript. I figure that it's out of scope for this project to support Flow, so I didn't bother with this test.

I added some utility functions to the react utils file that were useful for checking for the presence of jsx or a HOC.

I tried to use CompactStr and FxHashSet rather than vec and String where possible. I also tried to make this implementation as simple as possible, but there are a lot of use cases to account for.

I'm open to any feedback you have!

@taearls taearls requested a review from camc314 as a code owner July 4, 2025 21:37
@github-actions github-actions bot added A-linter Area - Linter A-cli Area - CLI C-enhancement Category - New feature or request labels Jul 4, 2025
@codspeed-hq
Copy link

codspeed-hq bot commented Jul 4, 2025

CodSpeed Performance Report

Merging #12084 will not alter performance

Comparing taearls:linter/react-display-name (6c85485) with main (0f63e75)1

Summary

✅ 4 untouched
⏩ 41 skipped2

Footnotes

  1. No successful run was found on main (b2b87c6) during the generation of this report, so 0f63e75 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 41 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@camc314 camc314 force-pushed the linter/react-display-name branch from 5a17d37 to 59cf2bd Compare September 30, 2025 15:56
@taearls taearls force-pushed the linter/react-display-name branch from 59cf2bd to 97eacca Compare October 4, 2025 16:01
@taearls
Copy link
Contributor Author

taearls commented Oct 4, 2025

@camc314 I fixed the build on this branch and rebased off of main. this is ready for review whenever you get a chance!

@taearls taearls force-pushed the linter/react-display-name branch 2 times, most recently from cadebe7 to 919325b Compare October 14, 2025 22:41
@taearls taearls force-pushed the linter/react-display-name branch from 8ff9ca2 to 927c171 Compare October 16, 2025 16:03
taearls added a commit to taearls/oxc that referenced this pull request Oct 17, 2025
Replace full AST iteration with symbol-based semantic analysis for better
performance and cleaner architecture.

Changes:
- Use semantic symbol iteration instead of iterating all AST nodes
- Leverage semantic references to detect displayName assignments
- Add helper functions for component detection and validation
- Detect Higher-Order Functions that return components with JSX
- Handle nested arrow functions and curried component patterns

Key improvements:
- Reduced iterations: Only process symbols + specific anonymous cases
- Semantic-based: Use reference tracking instead of manual HashMaps
- Better separation: Component detection vs displayName validation
- Maintained functionality: All 805 tests pass including HOF patterns

Implementation details:
- is_react_component_node(): Consolidates all component detection logic
- has_display_name_via_semantic(): Checks displayName via symbol references
- check_function_expression_component(): Detects direct JSX and HOF patterns
- Three-phase approach: symbols → anonymous exports → diagnostics

Addresses: oxc-project#12084 (comment)
@taearls taearls force-pushed the linter/react-display-name branch from f2d4321 to 02d4f44 Compare October 17, 2025 15:27
taearls added a commit to taearls/oxc that referenced this pull request Oct 17, 2025
Replace full AST iteration with symbol-based semantic analysis for better
performance and cleaner architecture.

Changes:
- Use semantic symbol iteration instead of iterating all AST nodes
- Leverage semantic references to detect displayName assignments
- Add helper functions for component detection and validation
- Detect Higher-Order Functions that return components with JSX
- Handle nested arrow functions and curried component patterns

Key improvements:
- Reduced iterations: Only process symbols + specific anonymous cases
- Semantic-based: Use reference tracking instead of manual HashMaps
- Better separation: Component detection vs displayName validation
- Maintained functionality: All 805 tests pass including HOF patterns

Implementation details:
- is_react_component_node(): Consolidates all component detection logic
- has_display_name_via_semantic(): Checks displayName via symbol references
- check_function_expression_component(): Detects direct JSX and HOF patterns
- Three-phase approach: symbols → anonymous exports → diagnostics

Addresses: oxc-project#12084 (comment)
taearls added a commit to taearls/oxc that referenced this pull request Oct 20, 2025
Replace full AST iteration with symbol-based semantic analysis for better
performance and cleaner architecture.

Changes:
- Use semantic symbol iteration instead of iterating all AST nodes
- Leverage semantic references to detect displayName assignments
- Add helper functions for component detection and validation
- Detect Higher-Order Functions that return components with JSX
- Handle nested arrow functions and curried component patterns

Key improvements:
- Reduced iterations: Only process symbols + specific anonymous cases
- Semantic-based: Use reference tracking instead of manual HashMaps
- Better separation: Component detection vs displayName validation
- Maintained functionality: All 805 tests pass including HOF patterns

Implementation details:
- is_react_component_node(): Consolidates all component detection logic
- has_display_name_via_semantic(): Checks displayName via symbol references
- check_function_expression_component(): Detects direct JSX and HOF patterns
- Three-phase approach: symbols → anonymous exports → diagnostics

Addresses: oxc-project#12084 (comment)
@taearls taearls force-pushed the linter/react-display-name branch from 1063655 to 0bc0383 Compare October 20, 2025 15:25
@connorshea
Copy link
Member

This'll be great to have, thank you!

@taearls taearls requested a review from camc314 October 22, 2025 14:54
@taearls
Copy link
Contributor Author

taearls commented Nov 13, 2025

@camc314 when you get a chance could you give this PR another look? Thanks!

@camc314 camc314 force-pushed the linter/react-display-name branch from 0bc0383 to 6a3e915 Compare November 14, 2025 13:24
camc314 pushed a commit to taearls/oxc that referenced this pull request Nov 14, 2025
Replace full AST iteration with symbol-based semantic analysis for better
performance and cleaner architecture.

Changes:
- Use semantic symbol iteration instead of iterating all AST nodes
- Leverage semantic references to detect displayName assignments
- Add helper functions for component detection and validation
- Detect Higher-Order Functions that return components with JSX
- Handle nested arrow functions and curried component patterns

Key improvements:
- Reduced iterations: Only process symbols + specific anonymous cases
- Semantic-based: Use reference tracking instead of manual HashMaps
- Better separation: Component detection vs displayName validation
- Maintained functionality: All 805 tests pass including HOF patterns

Implementation details:
- is_react_component_node(): Consolidates all component detection logic
- has_display_name_via_semantic(): Checks displayName via symbol references
- check_function_expression_component(): Detects direct JSX and HOF patterns
- Three-phase approach: symbols → anonymous exports → diagnostics

Addresses: oxc-project#12084 (comment)
camc314 pushed a commit to taearls/oxc that referenced this pull request Nov 14, 2025
Replace full AST iteration with symbol-based semantic analysis for better
performance and cleaner architecture.

Changes:
- Use semantic symbol iteration instead of iterating all AST nodes
- Leverage semantic references to detect displayName assignments
- Add helper functions for component detection and validation
- Detect Higher-Order Functions that return components with JSX
- Handle nested arrow functions and curried component patterns

Key improvements:
- Reduced iterations: Only process symbols + specific anonymous cases
- Semantic-based: Use reference tracking instead of manual HashMaps
- Better separation: Component detection vs displayName validation
- Maintained functionality: All 805 tests pass including HOF patterns

Implementation details:
- is_react_component_node(): Consolidates all component detection logic
- has_display_name_via_semantic(): Checks displayName via symbol references
- check_function_expression_component(): Detects direct JSX and HOF patterns
- Three-phase approach: symbols → anonymous exports → diagnostics

Addresses: oxc-project#12084 (comment)
@camc314 camc314 force-pushed the linter/react-display-name branch from 17023eb to 7b0f0d8 Compare November 14, 2025 13:29
Copy link
Member

@camchenry camchenry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Truly sorry this hasn't been reviewed earlier. I think this looks pretty good overall. The logic seems generally sound to me, and if the tests are passing then I think this rule is in good shape.

I've left some comments to improve the style a little bit and also be slightly more idiomatic for our codebase, but I don't think there's anything major that needs to be addressed. I believe if the merge conflicts are resolved as well, we can try to get this merged.

@camc314 Do you mind taking a look at this as well and see if you agree?

@taearls
Copy link
Contributor Author

taearls commented Dec 10, 2025

Truly sorry this hasn't been reviewed earlier. I think this looks pretty good overall. The logic seems generally sound to me, and if the tests are passing then I think this rule is in good shape.

I've left some comments to improve the style a little bit and also be slightly more idiomatic for our codebase, but I don't think there's anything major that needs to be addressed. I believe if the merge conflicts are resolved as well, we can try to get this merged.

@camc314 Do you mind taking a look at this as well and see if you agree?

Thanks for your feedback! I'll try to address it this week.

@camc314
Copy link
Contributor

camc314 commented Dec 10, 2025

Thanks for working so hard on this, it's a complex rule. Apologies for the delay in getting to it

@camc314 Do you mind taking a look at this as well and see if you agree?

Yeah, I agree - thank you for reviewing.

taearls and others added 2 commits December 20, 2025 11:17
Update display_name rule to use the new structured ReactVersion type
from main instead of string-based version parsing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@taearls taearls force-pushed the linter/react-display-name branch from c069a1b to 14816e8 Compare December 20, 2025 17:25
taearls and others added 6 commits December 20, 2025 11:39
- Remove .idea/ IDE configuration files
- Reset Cargo.lock to main's version (napi packages were incorrectly downgraded)
- Revert unrelated changes to tasks/website_formatter and tasks/website_linter

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Change is_hoc_call to use exact matching instead of ends_with pattern
- Matches ESLint react/display-name behavior
- Only matches: memo, forwardRef, React.memo, React.forwardRef
- Also fix documentation typo for componentWrapperFunctions setting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
This file was accidentally modified during a previous rebase.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Local tsgolint binary panics with "unknown rule" errors, causing
corrupted snapshot output. Restore proper snapshots from main branch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Another snapshot corrupted by outdated local tsgolint binary.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@taearls
Copy link
Contributor Author

taearls commented Dec 20, 2025

I have addressed all the feedback and rebased onto main. thanks for your patience! this is ready for another review when you get a chance @camc314 @camchenry

@taearls
Copy link
Contributor Author

taearls commented Jan 14, 2026

@camc314 @camchenry when you can, could I get a review on this? I think it's ready to go.

@overlookmotel overlookmotel removed A-parser Area - Parser A-semantic Area - Semantic A-cli Area - CLI A-minifier Area - Minifier A-transformer Area - Transformer / Transpiler A-codegen Area - Code Generation A-cfg Area - Control Flow Graph A-isolated-declarations Isolated Declarations A-ast-tools Area - AST tools A-editor Area - Editor and Language Server A-formatter Area - Formatter A-linter-plugins Area - Linter JS plugins A-ast Area - AST labels Jan 20, 2026
graphite-app bot pushed a commit that referenced this pull request Jan 23, 2026
This is a fixed up version of #12084 with merge conflicts resolved.
@camchenry
Copy link
Member

Hi @taearls. Sorry for the very long timeline in this PR, but we are going to go ahead and merge this! Thank you for all of your work on this. There are some merge conflicts currently, but I've pushed up fixes for those to a separate PR which we'll merge directly: #18426.

@camchenry camchenry closed this Jan 23, 2026
@taearls taearls deleted the linter/react-display-name branch January 23, 2026 05:36
@taearls
Copy link
Contributor Author

taearls commented Jan 23, 2026

Hi @taearls. Sorry for the very long timeline in this PR, but we are going to go ahead and merge this! Thank you for all of your work on this. There are some merge conflicts currently, but I've pushed up fixes for those to a separate PR which we'll merge directly: #18426.

I understand! I get that there have been higher priorities. Thanks for reviewing and accepting my PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter C-enhancement Category - New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

Comments