aboutsummaryrefslogtreecommitdiff
path: root/src/parser/grammar/paths.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/grammar/paths.rs')
-rw-r--r--src/parser/grammar/paths.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/parser/grammar/paths.rs b/src/parser/grammar/paths.rs
new file mode 100644
index 000000000..6efac2610
--- /dev/null
+++ b/src/parser/grammar/paths.rs
@@ -0,0 +1,49 @@
1use super::*;
2
3pub(super) fn is_path_start(p: &Parser) -> bool {
4 AnyOf(&[IDENT, SELF_KW, SUPER_KW, COLONCOLON]).is_ahead(p)
5}
6
7pub(super) fn use_path(p: &mut Parser) {
8 path(p)
9}
10
11pub(super) fn type_path(p: &mut Parser) {
12 path(p)
13}
14
15fn path(p: &mut Parser) {
16 if !is_path_start(p) {
17 return;
18 }
19 let path = p.start();
20 path_segment(p, true);
21 let mut qual = path.complete(p, PATH);
22 loop {
23 let use_tree = match p.nth(1) {
24 STAR | L_CURLY => true,
25 _ => false,
26 };
27 if p.at(COLONCOLON) && !use_tree {
28 let path = qual.precede(p);
29 p.bump();
30 path_segment(p, false);
31 let path = path.complete(p, PATH);
32 qual = path;
33 } else {
34 break;
35 }
36 }
37}
38
39fn path_segment(p: &mut Parser, first: bool) {
40 let segment = p.start();
41 if first {
42 p.eat(COLONCOLON);
43 }
44 match p.current() {
45 IDENT | SELF_KW | SUPER_KW => p.bump(),
46 _ => p.error().message("expected identifier").emit(),
47 };
48 segment.complete(p, PATH_SEGMENT);
49}