Skip to content

Conversation

takuji
Copy link
Contributor

@takuji takuji commented Sep 27, 2025

With this change, when an event handler name is detected, the underline in the error message will point only to the event handler name.

@takuji takuji requested a review from camc314 as a code owner September 27, 2025 04:10
@Copilot Copilot AI review requested due to automatic review settings September 27, 2025 04:10
Copy link
Contributor

graphite-app bot commented Sep 27, 2025

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

@github-actions github-actions bot added A-linter Area - Linter C-bug Category - Bug labels Sep 27, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves the error message positioning for the jsx-handler-names linter rule by making the underline point specifically to the event handler name rather than the entire expression. The change enhances the precision of error reporting by extracting and highlighting only the relevant handler name portion.

Key changes:

  • Refactored handler name extraction logic to return both the name and its specific span
  • Modified error diagnostic to use the precise handler name span instead of the entire expression container span
  • Added support for detecting "props" handlers to allow proper validation

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
crates/oxc_linter/src/rules/react/jsx_handler_names.rs Refactored handler name extraction with precise span tracking and added props handler detection
crates/oxc_linter/src/snapshots/react_jsx_handler_names.snap Updated test snapshots showing improved error message positioning

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

codspeed-hq bot commented Sep 27, 2025

CodSpeed Instrumentation Performance Report

Merging #14174 will not alter performance

Comparing takuji:jsx-handler-names-improve-handler-name-position-in-error-messages (1c77a4b) with main (11dd63b)1

Summary

✅ 4 untouched
⏩ 33 skipped2

Footnotes

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

  2. 33 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 self-assigned this Sep 27, 2025
@takuji takuji requested a review from Copilot September 30, 2025 14:57
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@takuji takuji force-pushed the jsx-handler-names-improve-handler-name-position-in-error-messages branch from 72594b0 to 4af3a1a Compare October 1, 2025 22:41
@takuji takuji requested a review from Copilot October 1, 2025 22:45
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@takuji takuji force-pushed the jsx-handler-names-improve-handler-name-position-in-error-messages branch from 4af3a1a to 11f2e81 Compare October 2, 2025 15:20
@takuji takuji requested a review from Copilot October 2, 2025 15:26
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 379 to 398
member_expr: &StaticMemberExpression,
ctx: &LintContext,
) -> (CompactStr, Span, bool) {
let name = member_expr.property.name.as_str();
let span = member_expr.property.span;
match &member_expr.object {
Expression::ThisExpression(_) => (name.into(), span, false),
Expression::Identifier(ident) => {
let obj_name = ident.name.as_str();
(name.into(), span, obj_name == "props")
}
Expression::StaticMemberExpression(expr) => {
let (obj_name, _, _) = get_event_handler_name_from_static_member_expression(expr, ctx);
(name.into(), span, obj_name == "props")
}
_ => (ctx.source_range(member_expr.span).into(), member_expr.span, false),
}
Copy link
Preview

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

This recursive call could lead to deep recursion for deeply nested member expressions. Consider adding a recursion depth limit or iterative implementation to prevent stack overflow.

Suggested change
member_expr: &StaticMemberExpression,
ctx: &LintContext,
) -> (CompactStr, Span, bool) {
let name = member_expr.property.name.as_str();
let span = member_expr.property.span;
match &member_expr.object {
Expression::ThisExpression(_) => (name.into(), span, false),
Expression::Identifier(ident) => {
let obj_name = ident.name.as_str();
(name.into(), span, obj_name == "props")
}
Expression::StaticMemberExpression(expr) => {
let (obj_name, _, _) = get_event_handler_name_from_static_member_expression(expr, ctx);
(name.into(), span, obj_name == "props")
}
_ => (ctx.source_range(member_expr.span).into(), member_expr.span, false),
}
mut member_expr: &StaticMemberExpression,
ctx: &LintContext,
) -> (CompactStr, Span, bool) {
let name = member_expr.property.name.as_str();
let span = member_expr.property.span;
let mut obj = &member_expr.object;
// Track if the deepest object is "props"
let mut is_props = false;
let mut obj_name: Option<&str> = None;
loop {
match obj {
Expression::ThisExpression(_) => {
obj_name = Some("this");
break;
}
Expression::Identifier(ident) => {
obj_name = Some(ident.name.as_str());
is_props = ident.name.as_str() == "props";
break;
}
Expression::StaticMemberExpression(expr) => {
// Go deeper
obj = &expr.object;
obj_name = Some(expr.property.name.as_str());
is_props = expr.property.name.as_str() == "props";
// Continue loop
}
_ => {
obj_name = None;
break;
}
}
}
let obj_name_str = obj_name.unwrap_or_else(|| ctx.source_range(member_expr.span).as_ref());
(name.into(), span, is_props)

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

@takuji takuji Oct 4, 2025

Choose a reason for hiding this comment

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

Modified not to use either recursive function calls or a loop.

fn get_event_handler_name_from_static_member_expression(
member_expr: &StaticMemberExpression,
) -> (CompactStr, Span, bool) {
let name = member_expr.property.name.as_str();
let span = member_expr.property.span;
match &member_expr.object {
Expression::Identifier(ident) => {
let obj_name = ident.name.as_str();
(name.into(), span, obj_name == "props") // props.handleChange or obj.handleChange
}
Expression::StaticMemberExpression(expr) => {
if let Expression::ThisExpression(_) = &expr.object {
let obj_name = expr.property.name.as_str();
(name.into(), span, obj_name == "props") // this.props.handleChange or this.obj.handleChange
} else {
(name.into(), span, false) // foo.props.handleChange, props.foo.handleChange, foo.bar.handleChange, etc.
}
}
_ => (name.into(), span, false), // this.handleChange
}
}

@takuji takuji force-pushed the jsx-handler-names-improve-handler-name-position-in-error-messages branch from 11f2e81 to b585030 Compare October 2, 2025 16:55
@takuji takuji force-pushed the jsx-handler-names-improve-handler-name-position-in-error-messages branch from 5748611 to 116260b Compare October 2, 2025 17:19
@takuji takuji requested a review from Copilot October 2, 2025 17:32
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

_ => {
if !self.check_local_variables && !value_expr.is_member_expression() {
return;
}
Copy link
Preview

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

Using shrink(1) on the expression container span may not provide the correct handler name span for all expression types. This fallback should either be more specific about span calculation or have a comment explaining why shrink(1) is appropriate here.

Suggested change
}
}
// For other expression types, we use shrink(1) to approximate the handler name span,
// as these are typically simple expressions (e.g., literals, calls) where the handler name
// is expected to be at the end of the expression container. If more specific handling is needed,
// it should be added here.

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

@takuji takuji Oct 4, 2025

Choose a reason for hiding this comment

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

Added a comment.

// For other expressions types, use the whole content inside the braces as the handler name,
// which will be marked as a bad handler name if the prop key is an event handler prop.

@takuji takuji force-pushed the jsx-handler-names-improve-handler-name-position-in-error-messages branch from f9f431d to 1c77a4b Compare October 4, 2025 04:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linter Area - Linter C-bug Category - Bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants