Skip to content

Commit fcf3432

Browse files
committed
Try to naively skip attributes when parsing generics
1 parent ca3ba9c commit fcf3432

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/racer/matchers.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,27 @@ fn match_mod_inner(
425425
}
426426

427427
fn find_generics_end(blob: &str) -> Option<BytePos> {
428+
// Naive version that attempts to skip over attributes
429+
let mut in_attr = false;
430+
let mut attr_level = 0;
431+
428432
let mut level = 0;
429433
for (i, b) in blob.as_bytes().into_iter().enumerate() {
434+
// Naively skip attributes `#[...]`
435+
if in_attr {
436+
match b {
437+
b'[' => attr_level += 1,
438+
b']' => {
439+
attr_level -=1;
440+
if attr_level == 0 {
441+
in_attr = false;
442+
continue;
443+
}
444+
},
445+
_ => continue,
446+
}
447+
}
448+
// ...otherwise just try to find the last `>`
430449
match b {
431450
b'{' | b'(' | b';' => return None,
432451
b'<' => level += 1,
@@ -436,6 +455,7 @@ fn find_generics_end(blob: &str) -> Option<BytePos> {
436455
return Some(i.into());
437456
}
438457
}
458+
b'#' if blob.bytes().nth(i + 1) == Some(b'[') => in_attr = true,
439459
_ => {}
440460
}
441461
}
@@ -871,3 +891,24 @@ pub fn match_impl(decl: String, context: &MatchCxt<'_, '_>, offset: BytePos) ->
871891
}
872892
Some(out)
873893
}
894+
895+
#[cfg(test)]
896+
mod tests {
897+
use super::*;
898+
#[test]
899+
fn find_generics_end() {
900+
use super::find_generics_end;
901+
assert_eq!(
902+
find_generics_end("Vec<T, #[unstable(feature = \"\", issue = \"\"] A: AllocRef = Global>"),
903+
Some(BytePos(64))
904+
);
905+
assert_eq!(
906+
find_generics_end("Vec<T, A: AllocRef = Global>"),
907+
Some(BytePos(27))
908+
);
909+
assert_eq!(
910+
find_generics_end("Result<Vec<String>, Option<&str>>"),
911+
Some(BytePos(32))
912+
);
913+
}
914+
}

0 commit comments

Comments
 (0)