diff options
Diffstat (limited to '')
-rw-r--r-- | src/tools/rust-analyzer/crates/parser/src/tests/prefix_entries.rs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/parser/src/tests/prefix_entries.rs b/src/tools/rust-analyzer/crates/parser/src/tests/prefix_entries.rs new file mode 100644 index 000000000..e626b4f27 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/src/tests/prefix_entries.rs @@ -0,0 +1,107 @@ +use crate::{LexedStr, PrefixEntryPoint, Step}; + +#[test] +fn vis() { + check(PrefixEntryPoint::Vis, "pub(crate) fn foo() {}", "pub(crate)"); + check(PrefixEntryPoint::Vis, "fn foo() {}", ""); + check(PrefixEntryPoint::Vis, "pub(fn foo() {}", "pub"); + check(PrefixEntryPoint::Vis, "pub(crate fn foo() {}", "pub(crate"); + check(PrefixEntryPoint::Vis, "crate fn foo() {}", "crate"); +} + +#[test] +fn block() { + check(PrefixEntryPoint::Block, "{}, 92", "{}"); + check(PrefixEntryPoint::Block, "{, 92)", "{, 92)"); + check(PrefixEntryPoint::Block, "()", ""); +} + +#[test] +fn stmt() { + check(PrefixEntryPoint::Stmt, "92; fn", "92"); + check(PrefixEntryPoint::Stmt, "let _ = 92; 1", "let _ = 92"); + check(PrefixEntryPoint::Stmt, "pub fn f() {} = 92", "pub fn f() {}"); + check(PrefixEntryPoint::Stmt, "struct S;;", "struct S;"); + check(PrefixEntryPoint::Stmt, "fn f() {};", "fn f() {}"); + check(PrefixEntryPoint::Stmt, ";;;", ";"); + check(PrefixEntryPoint::Stmt, "+", "+"); + check(PrefixEntryPoint::Stmt, "@", "@"); + check(PrefixEntryPoint::Stmt, "loop {} - 1", "loop {}"); +} + +#[test] +fn pat() { + check(PrefixEntryPoint::Pat, "x y", "x"); + check(PrefixEntryPoint::Pat, "fn f() {}", "fn"); + // FIXME: This one is wrong, we should consume only one pattern. + check(PrefixEntryPoint::Pat, ".. ..", ".. .."); +} + +#[test] +fn ty() { + check(PrefixEntryPoint::Ty, "fn() foo", "fn()"); + check(PrefixEntryPoint::Ty, "Clone + Copy + fn", "Clone + Copy +"); + check(PrefixEntryPoint::Ty, "struct f", "struct"); +} + +#[test] +fn expr() { + check(PrefixEntryPoint::Expr, "92 92", "92"); + check(PrefixEntryPoint::Expr, "+1", "+"); + check(PrefixEntryPoint::Expr, "-1", "-1"); + check(PrefixEntryPoint::Expr, "fn foo() {}", "fn"); + check(PrefixEntryPoint::Expr, "#[attr] ()", "#[attr] ()"); +} + +#[test] +fn path() { + check(PrefixEntryPoint::Path, "foo::bar baz", "foo::bar"); + check(PrefixEntryPoint::Path, "foo::<> baz", "foo::<>"); + check(PrefixEntryPoint::Path, "foo<> baz", "foo<>"); + check(PrefixEntryPoint::Path, "Fn() -> i32?", "Fn() -> i32"); + // FIXME: This shouldn't be accepted as path actually. + check(PrefixEntryPoint::Path, "<_>::foo", "<_>::foo"); +} + +#[test] +fn item() { + // FIXME: This shouldn't consume the semicolon. + check(PrefixEntryPoint::Item, "fn foo() {};", "fn foo() {};"); + check(PrefixEntryPoint::Item, "#[attr] pub struct S {} 92", "#[attr] pub struct S {}"); + check(PrefixEntryPoint::Item, "item!{}?", "item!{}"); + check(PrefixEntryPoint::Item, "????", "?"); +} + +#[test] +fn meta_item() { + check(PrefixEntryPoint::MetaItem, "attr, ", "attr"); + check(PrefixEntryPoint::MetaItem, "attr(some token {stream});", "attr(some token {stream})"); + check(PrefixEntryPoint::MetaItem, "path::attr = 2 * 2!", "path::attr = 2 * 2"); +} + +#[track_caller] +fn check(entry: PrefixEntryPoint, input: &str, prefix: &str) { + let lexed = LexedStr::new(input); + let input = lexed.to_input(); + + let mut n_tokens = 0; + for step in entry.parse(&input).iter() { + match step { + Step::Token { n_input_tokens, .. } => n_tokens += n_input_tokens as usize, + Step::Enter { .. } | Step::Exit | Step::Error { .. } => (), + } + } + + let mut i = 0; + loop { + if n_tokens == 0 { + break; + } + if !lexed.kind(i).is_trivia() { + n_tokens -= 1; + } + i += 1; + } + let buf = &lexed.as_str()[..lexed.text_start(i)]; + assert_eq!(buf, prefix); +} |