diff --git a/crates/oxc_linter/src/rules/eslint/yoda.rs b/crates/oxc_linter/src/rules/eslint/yoda.rs index 6f1298efe5722..19efb31b52def 100644 --- a/crates/oxc_linter/src/rules/eslint/yoda.rs +++ b/crates/oxc_linter/src/rules/eslint/yoda.rs @@ -266,61 +266,53 @@ fn is_not_yoda(expr: &BinaryExpression) -> bool { #[allow(clippy::cast_possible_truncation)] fn do_diagnostic_with_fix(expr: &BinaryExpression, ctx: &LintContext, never: bool) { ctx.diagnostic_with_fix(yoda_diagnostic(expr.span, never, expr.operator.as_str()), |fix| { - let flipped_operator = flip_operator(expr.operator); - - let left_str = ctx.source_range(expr.left.span()); - let right_str = ctx.source_range(expr.right.span()); - let flipped_operator_str = flipped_operator.as_str(); + let left_span = expr.left.span(); + let right_span = expr.right.span(); let operator_str = expr.operator.as_str(); - let source_str = ctx.source_range( - Span::new(expr.left.span().end, expr.right.span().start) + let str_between_left_and_right = ctx.source_range( + Span::new(left_span.end, right_span.start) ); - let source_chars = source_str.char_indices().collect::>(); - - let search_start_position = expr.left.span().end; - - let operator_position_start = source_chars.windows(operator_str.len()).find(|str| { - if str.iter().enumerate().all(|(i, (_pos, c))| *c == operator_str.chars().nth(i).unwrap()) { - !ctx.comments().iter().any(|c| { - c.span.start <= (str[0].0 as u32) + search_start_position && (str[0].0 as u32) + operator_str.len() as u32 + search_start_position <= c.span.end - }) - } else { - false - } - }); - - let Some(operator_position_start) = operator_position_start else { - debug_assert!(false); - return fix.noop(); - }; - - let operator_position_start = search_start_position + operator_position_start[0].0 as u32; + let (operator_start, operator_end) = str_between_left_and_right + .as_bytes() + .windows(operator_str.len()) + .enumerate() + .find_map(|(index, chunk)| { + if chunk == operator_str.as_bytes() { + let pos_start = index as u32 + left_span.end; + let pos_end = pos_start + operator_str.len() as u32; + if !ctx.comments().iter().any(|comment| comment.span.start <= pos_start && pos_end <= comment.span.end) { + return Some((pos_start, pos_end)); + } + } + None + }) + .unwrap(); - let operator_position_end = operator_position_start + operator_str.len() as u32; - let str_between_left_and_operator = ctx.source_range(Span::new(expr.left.span().end, operator_position_start)); - let str_between_operator_and_right = ctx.source_range(Span::new(operator_position_end, expr.right.span().start)); + let str_between_left_and_operator = ctx.source_range(Span::new(left_span.end, operator_start)); + let str_between_operator_and_right = ctx.source_range(Span::new(operator_end, right_span.start)); - let left_start = expr.left.span().start; - let left_prev_token = if left_start > 0 && (expr.right.is_literal() || expr.right.is_identifier_reference() ) { - let tokens = ctx.source_range(Span::new(0, left_start)); + let left_prev_token = if left_span.start > 0 && (expr.right.is_literal() || expr.right.is_identifier_reference() ) { + let tokens = ctx.source_range(Span::new(0, left_span.start)); let token = tokens.chars().last(); match_token(token) } else { false }; - let right_end = expr.right.span().end; let source_size = u32::try_from(ctx.source_text().len()).unwrap(); - let right_next_token = if right_end < source_size && (expr.left.is_literal() || expr.left.is_identifier_reference()) { - let tokens = ctx.source_range(Span::new(right_end, source_size)); + let right_next_token = if right_span.end < source_size && (expr.left.is_literal() || expr.left.is_identifier_reference()) { + let tokens = ctx.source_range(Span::new(right_span.end, source_size)); let token = tokens.chars().next(); match_token(token) } else { false }; + let left_str = ctx.source_range(left_span); + let right_str = ctx.source_range(right_span); + let flipped_operator_str = flip_operator(expr.operator).as_str(); let replacement = format!( "{}{right_str}{str_between_left_and_operator}{flipped_operator_str}{str_between_operator_and_right}{left_str}{}", if left_prev_token { " " } else { "" },