Skip to content

Commit 3b69346

Browse files
author
caiuswang
committed
fix(core): correct deletion index calculation for char indices
Update get_deletion_indices to use byte indices instead of char indices when checking deletion ranges. This ensures accurate handling of Unicode characters and prevents off-by-one errors during range checks.
1 parent 0d42b4b commit 3b69346

File tree

2 files changed

+120
-6
lines changed

2 files changed

+120
-6
lines changed

crates/core/src/inline_snippets.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,21 +526,21 @@ fn get_deletion_indices(input: &str, ranges: &[Range<usize>]) -> Vec<usize> {
526526
let mut is_single_quoted_string_literal = false;
527527
let mut deletion_range = RewriteRange::Unknown;
528528
let mut last_comma: Option<usize> = None;
529-
let mut chars = input.chars().enumerate().peekable();
529+
let mut chars = input.char_indices().enumerate().peekable();
530530
let mut result: Vec<usize> = vec![];
531-
while let Some((index, c)) = chars.next() {
532-
if is_in_deletion_range(index, &deletion_ranges) {
531+
while let Some((index, (byte_index, c))) = chars.next() {
532+
if is_in_deletion_range(byte_index, &deletion_ranges) {
533533
deletion_range = RewriteRange::Rewrite;
534534
} else if let RewriteRange::Rewrite = deletion_range {
535535
deletion_range = RewriteRange::PostRewrite
536536
}
537537
match c {
538538
'/' => {
539-
if let Some((_, '/')) = chars.peek() {
539+
if let Some((_, (_, '/'))) = chars.peek() {
540540
if !in_multiline_comment {
541541
in_single_line_comment = true;
542542
}
543-
} else if let Some((_, '*')) = chars.peek() {
543+
} else if let Some((_, (_,'*'))) = chars.peek() {
544544
in_multiline_comment = true;
545545
}
546546
if !in_single_line_comment && !in_multiline_comment {
@@ -559,7 +559,7 @@ fn get_deletion_indices(input: &str, ranges: &[Range<usize>]) -> Vec<usize> {
559559
if is_double_quoted_string_literal || is_single_quoted_string_literal {
560560
continue;
561561
}
562-
if in_multiline_comment && matches!(chars.peek(), Some((_, '/'))) {
562+
if in_multiline_comment && matches!(chars.peek(), Some((_, (_, '/')))) {
563563
in_multiline_comment = false;
564564
chars.next().unwrap();
565565
} else if !in_single_line_comment && !in_multiline_comment {

crates/core/src/test.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16790,3 +16790,117 @@ fn csharp_throw_exception() {
1679016790
})
1679116791
.unwrap();
1679216792
}
16793+
16794+
#[test]
16795+
fn run_pattern_file_with_utf8_content() {
16796+
16797+
run_test_expected({
16798+
TestArgExpected {
16799+
pattern: r#"
16800+
|language java
16801+
|file($body) where {
16802+
| $body <: contains {
16803+
| bubble() field_declaration($modifiers, $declarator) where {
16804+
| $replaced_ann = "",
16805+
| $delete_annotations = [],
16806+
| maybe $modifiers <: contains bubble($replaced_ann) annotation(name=$ann_name) as $anno where {
16807+
| if ($ann_name <: "Column") {
16808+
| if ($replaced_ann <: "") { $replaced_ann = $anno },
16809+
| $anno => .
16810+
| } else if ($ann_name <: "Convert") {
16811+
| if ($replaced_ann <: not "") { $replaced_ann => . },
16812+
| $replaced_ann = $anno
16813+
| }
16814+
| },
16815+
| if ($replaced_ann <: not "") {
16816+
| log($replaced_ann),
16817+
| $replaced_ann => `@TableField`
16818+
| },
16819+
| $replaced_ann = ``
16820+
| }
16821+
| }
16822+
|}
16823+
|"#
16824+
.trim_margin()
16825+
.unwrap(),
16826+
source: r#"
16827+
|package a.b;
16828+
|
16829+
|import javax.persistence.Entity;
16830+
|
16831+
|public class AEntity implements Serializable {
16832+
| /**
16833+
| * 大大大
16834+
| */
16835+
| /**
16836+
| * 0. 大大 1. 大大大大大 2. 大大大大 3大大大大大大 4. 大大大大.
16837+
| */
16838+
| /**
16839+
| * 0. 大大 1. 大大大大大 2. 大大大大 3. 大大大大大大大 4. 大大大大大大大 5. 大大大大大大大大.
16840+
| */
16841+
| /**
16842+
| * 0. 大大 1. 大大大大 2. 大大大大 3. 大大大大 4. 大大大大 5. 大大大大.
16843+
| */
16844+
| /**
16845+
| * 大大大大大.
16846+
| */
16847+
| /**
16848+
| * 大大大大大大大大.
16849+
| */
16850+
| @Convert(converter = T.class)
16851+
| @Column(name = "messages")
16852+
| private Messeges messages;
16853+
|
16854+
|
16855+
| @Column(name = "field" )
16856+
| private String field;
16857+
|
16858+
|
16859+
| @Column(name = "created_time", nullable = false, length = 19)
16860+
| private Date createdTime;
16861+
|}
16862+
|"#
16863+
.trim_margin()
16864+
.unwrap(),
16865+
expected: r#"
16866+
|package a.b;
16867+
|
16868+
|import javax.persistence.Entity;
16869+
|
16870+
|public class AEntity implements Serializable {
16871+
| /**
16872+
| * 大大大
16873+
| */
16874+
| /**
16875+
| * 0. 大大 1. 大大大大大 2. 大大大大 3大大大大大大 4. 大大大大.
16876+
| */
16877+
| /**
16878+
| * 0. 大大 1. 大大大大大 2. 大大大大 3. 大大大大大大大 4. 大大大大大大大 5. 大大大大大大大大.
16879+
| */
16880+
| /**
16881+
| * 0. 大大 1. 大大大大 2. 大大大大 3. 大大大大 4. 大大大大 5. 大大大大.
16882+
| */
16883+
| /**
16884+
| * 大大大大大.
16885+
| */
16886+
| /**
16887+
| * 大大大大大大大大.
16888+
| */
16889+
| @TableField
16890+
| private Messeges messages;
16891+
|
16892+
|
16893+
| @TableField
16894+
| private String field;
16895+
|
16896+
|
16897+
| @TableField
16898+
| private Date createdTime;
16899+
|}
16900+
|"#
16901+
.trim_margin()
16902+
.unwrap(),
16903+
}
16904+
})
16905+
.unwrap();
16906+
}

0 commit comments

Comments
 (0)