|
| 1 | +use crate::{LexedStr, PrefixEntryPoint, Step}; |
| 2 | + |
| 3 | +#[test] |
| 4 | +fn vis() { |
| 5 | + check(PrefixEntryPoint::Vis, "pub(crate) fn foo() {}", "pub(crate)"); |
| 6 | + check(PrefixEntryPoint::Vis, "fn foo() {}", ""); |
| 7 | + check(PrefixEntryPoint::Vis, "pub(fn foo() {}", "pub"); |
| 8 | + check(PrefixEntryPoint::Vis, "pub(crate fn foo() {}", "pub(crate"); |
| 9 | + check(PrefixEntryPoint::Vis, "crate fn foo() {}", "crate"); |
| 10 | +} |
| 11 | + |
| 12 | +#[test] |
| 13 | +fn block() { |
| 14 | + check(PrefixEntryPoint::Block, "{}, 92", "{}"); |
| 15 | + check(PrefixEntryPoint::Block, "{, 92)", "{, 92)"); |
| 16 | + check(PrefixEntryPoint::Block, "()", ""); |
| 17 | +} |
| 18 | + |
| 19 | +#[test] |
| 20 | +fn stmt() { |
| 21 | + check(PrefixEntryPoint::Stmt, "92; fn", "92"); |
| 22 | + check(PrefixEntryPoint::Stmt, "let _ = 92; 1", "let _ = 92"); |
| 23 | + check(PrefixEntryPoint::Stmt, "pub fn f() {} = 92", "pub fn f() {}"); |
| 24 | + check(PrefixEntryPoint::Stmt, "struct S;;", "struct S;"); |
| 25 | + check(PrefixEntryPoint::Stmt, "fn f() {};", "fn f() {}"); |
| 26 | + check(PrefixEntryPoint::Stmt, ";;;", ";"); |
| 27 | + check(PrefixEntryPoint::Stmt, "+", "+"); |
| 28 | + check(PrefixEntryPoint::Stmt, "@", "@"); |
| 29 | + check(PrefixEntryPoint::Stmt, "loop {} - 1", "loop {}"); |
| 30 | +} |
| 31 | + |
| 32 | +#[test] |
| 33 | +fn pat() { |
| 34 | + check(PrefixEntryPoint::Pat, "x y", "x"); |
| 35 | + check(PrefixEntryPoint::Pat, "fn f() {}", "fn"); |
| 36 | + // FIXME: This one is wrong, we should consume only one pattern. |
| 37 | + check(PrefixEntryPoint::Pat, ".. ..", ".. .."); |
| 38 | +} |
| 39 | + |
| 40 | +#[test] |
| 41 | +fn ty() { |
| 42 | + check(PrefixEntryPoint::Ty, "fn() foo", "fn()"); |
| 43 | + check(PrefixEntryPoint::Ty, "Clone + Copy + fn", "Clone + Copy +"); |
| 44 | + check(PrefixEntryPoint::Ty, "struct f", "struct"); |
| 45 | +} |
| 46 | + |
| 47 | +#[test] |
| 48 | +fn expr() { |
| 49 | + check(PrefixEntryPoint::Expr, "92 92", "92"); |
| 50 | + check(PrefixEntryPoint::Expr, "+1", "+"); |
| 51 | + check(PrefixEntryPoint::Expr, "-1", "-1"); |
| 52 | + check(PrefixEntryPoint::Expr, "fn foo() {}", "fn"); |
| 53 | + check(PrefixEntryPoint::Expr, "#[attr] ()", "#[attr] ()"); |
| 54 | +} |
| 55 | + |
| 56 | +#[test] |
| 57 | +fn path() { |
| 58 | + check(PrefixEntryPoint::Path, "foo::bar baz", "foo::bar"); |
| 59 | + check(PrefixEntryPoint::Path, "foo::<> baz", "foo::<>"); |
| 60 | + check(PrefixEntryPoint::Path, "foo<> baz", "foo<>"); |
| 61 | + check(PrefixEntryPoint::Path, "Fn() -> i32?", "Fn() -> i32"); |
| 62 | + // FIXME: This shouldn't be accepted as path actually. |
| 63 | + check(PrefixEntryPoint::Path, "<_>::foo", "<_>::foo"); |
| 64 | +} |
| 65 | + |
| 66 | +#[test] |
| 67 | +fn item() { |
| 68 | + // FIXME: This shouldn't consume the semicolon. |
| 69 | + check(PrefixEntryPoint::Item, "fn foo() {};", "fn foo() {};"); |
| 70 | + check(PrefixEntryPoint::Item, "#[attr] pub struct S {} 92", "#[attr] pub struct S {}"); |
| 71 | + check(PrefixEntryPoint::Item, "item!{}?", "item!{}"); |
| 72 | + check(PrefixEntryPoint::Item, "????", "?"); |
| 73 | +} |
| 74 | + |
| 75 | +#[test] |
| 76 | +fn meta_item() { |
| 77 | + check(PrefixEntryPoint::MetaItem, "attr, ", "attr"); |
| 78 | + check(PrefixEntryPoint::MetaItem, "attr(some token {stream});", "attr(some token {stream})"); |
| 79 | + check(PrefixEntryPoint::MetaItem, "path::attr = 2 * 2!", "path::attr = 2 * 2"); |
| 80 | +} |
| 81 | + |
| 82 | +#[track_caller] |
| 83 | +fn check(entry: PrefixEntryPoint, input: &str, prefix: &str) { |
| 84 | + let lexed = LexedStr::new(input); |
| 85 | + let input = lexed.to_input(); |
| 86 | + |
| 87 | + let mut n_tokens = 0; |
| 88 | + for step in entry.parse(&input).iter() { |
| 89 | + match step { |
| 90 | + Step::Token { n_input_tokens, .. } => n_tokens += n_input_tokens as usize, |
| 91 | + Step::Enter { .. } | Step::Exit | Step::Error { .. } => (), |
| 92 | + } |
| 93 | + } |
| 94 | + |
| 95 | + let mut i = 0; |
| 96 | + loop { |
| 97 | + if n_tokens == 0 { |
| 98 | + break; |
| 99 | + } |
| 100 | + if !lexed.kind(i).is_trivia() { |
| 101 | + n_tokens -= 1; |
| 102 | + } |
| 103 | + i += 1; |
| 104 | + } |
| 105 | + let buf = &lexed.as_str()[..lexed.text_start(i)]; |
| 106 | + assert_eq!(buf, prefix); |
| 107 | +} |
0 commit comments