Skip to content

Commit c89da93

Browse files
committed
fix(linter): false positive in eslint/curly on windows (#10671)
### TL;DR Fixed a false positive in the `curly` eslint rule when running on windows (`CRLF` line endings) ### What changed? since `\r\n` is two chars, `get_next_char_offset` was (incorrectly) returning a new line at the start of the string. Now, it checks for the `\r\n` pattern, to determine how many chars to skip (1 or 2) fixes #9600
1 parent 4861a62 commit c89da93

File tree

1 file changed

+30
-2
lines changed
  • crates/oxc_linter/src/rules/eslint

1 file changed

+30
-2
lines changed

crates/oxc_linter/src/rules/eslint/curly.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,16 @@ fn is_lexical_declaration(node: &Statement) -> bool {
391391

392392
#[expect(clippy::cast_possible_truncation)]
393393
fn get_next_char_offset(span: Span, ctx: &LintContext) -> Option<u32> {
394-
let next_char = ctx.source_text()[(span.end as usize)..].chars().next();
395-
next_char.map(|c| span.end + c.len_utf8() as u32)
394+
let src = ctx.source_text();
395+
let start = span.end as usize;
396+
397+
if let Some(tail) = src.get(start..) {
398+
if tail.starts_with("\r\n") || tail.starts_with("\n\r") {
399+
return Some(span.end + 2);
400+
}
401+
}
402+
403+
src[start..].chars().next().map(|c| span.end + c.len_utf8() as u32)
396404
}
397405

398406
#[expect(clippy::cast_possible_truncation)] // for `as i32`
@@ -801,6 +809,26 @@ fn test() {
801809
"if (a) while (cond) for (;;) for (key in obj) { if (b) foo(); } else bar();",
802810
Some(serde_json::json!(["multi"])),
803811
),
812+
(
813+
" const isIterable = (obj: any) : obj is Iterable<IgnoreRule> => {
814+
if (obj === null) return false;
815+
else if (typeof obj === 'string') return false;
816+
else return typeof value[Symbol.iterator] === 'function';
817+
};",
818+
Some(serde_json::json!(["multi"])),
819+
),
820+
(
821+
"const isIterable = (obj: any): obj is Iterable<IgnoreRule> => {\r\n if (obj === null) return false;\r\n else if (typeof obj === 'string') return false;\r\n else return typeof value[Symbol.iterator] === 'function';\r\n};\r\n",
822+
Some(serde_json::json!(["multi-line"])),
823+
),
824+
(
825+
" const isIterable = (obj: any) : obj is Iterable<IgnoreRule> => {
826+
if (obj === null) return false;
827+
else if (typeof obj === 'string') return false;
828+
else return typeof value[Symbol.iterator] === 'function';
829+
};",
830+
Some(serde_json::json!(["multi"])),
831+
),
804832
];
805833

806834
let fail = vec![

0 commit comments

Comments
 (0)