aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser')
-rw-r--r--crates/ra_parser/src/grammar.rs59
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs44
-rw-r--r--crates/ra_parser/src/lib.rs24
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs4
4 files changed, 120 insertions, 11 deletions
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index f8ed1299a..67eae749d 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -49,6 +49,27 @@ pub(crate) fn root(p: &mut Parser) {
49 m.complete(p, SOURCE_FILE); 49 m.complete(p, SOURCE_FILE);
50} 50}
51 51
52pub(crate) fn macro_items(p: &mut Parser) {
53 let m = p.start();
54 items::mod_contents(p, false);
55 m.complete(p, MACRO_ITEMS);
56}
57
58pub(crate) fn macro_stmts(p: &mut Parser) {
59 let m = p.start();
60
61 while !p.at(EOF) {
62 if p.current() == SEMI {
63 p.bump();
64 continue;
65 }
66
67 expressions::stmt(p, expressions::StmtWithSemi::Optional);
68 }
69
70 m.complete(p, MACRO_STMTS);
71}
72
52pub(crate) fn path(p: &mut Parser) { 73pub(crate) fn path(p: &mut Parser) {
53 paths::type_path(p); 74 paths::type_path(p);
54} 75}
@@ -66,9 +87,45 @@ pub(crate) fn pattern(p: &mut Parser) {
66} 87}
67 88
68pub(crate) fn stmt(p: &mut Parser, with_semi: bool) { 89pub(crate) fn stmt(p: &mut Parser, with_semi: bool) {
90 let with_semi = match with_semi {
91 true => expressions::StmtWithSemi::Yes,
92 false => expressions::StmtWithSemi::No,
93 };
94
69 expressions::stmt(p, with_semi) 95 expressions::stmt(p, with_semi)
70} 96}
71 97
98pub(crate) fn block(p: &mut Parser) {
99 expressions::block(p);
100}
101
102// Parse a meta item , which excluded [], e.g : #[ MetaItem ]
103pub(crate) fn meta_item(p: &mut Parser) {
104 fn is_delimiter(p: &mut Parser) -> bool {
105 match p.current() {
106 L_CURLY | L_PAREN | L_BRACK => true,
107 _ => false,
108 }
109 }
110
111 if is_delimiter(p) {
112 items::token_tree(p);
113 return;
114 }
115
116 let m = p.start();
117 while !p.at(EOF) {
118 if is_delimiter(p) {
119 items::token_tree(p);
120 break;
121 } else {
122 p.bump();
123 }
124 }
125
126 m.complete(p, TOKEN_TREE);
127}
128
72pub(crate) fn item(p: &mut Parser) { 129pub(crate) fn item(p: &mut Parser) {
73 items::item_or_macro(p, true, items::ItemFlavor::Mod) 130 items::item_or_macro(p, true, items::ItemFlavor::Mod)
74} 131}
@@ -110,7 +167,7 @@ impl BlockLike {
110 } 167 }
111} 168}
112 169
113fn opt_visibility(p: &mut Parser) -> bool { 170pub(crate) fn opt_visibility(p: &mut Parser) -> bool {
114 match p.current() { 171 match p.current() {
115 PUB_KW => { 172 PUB_KW => {
116 let m = p.start(); 173 let m = p.start();
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index 06f2b45b1..8df9035e9 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -4,6 +4,12 @@ pub(crate) use self::atom::match_arm_list;
4pub(super) use self::atom::{literal, LITERAL_FIRST}; 4pub(super) use self::atom::{literal, LITERAL_FIRST};
5use super::*; 5use super::*;
6 6
7pub(super) enum StmtWithSemi {
8 Yes,
9 No,
10 Optional,
11}
12
7const EXPR_FIRST: TokenSet = LHS_FIRST; 13const EXPR_FIRST: TokenSet = LHS_FIRST;
8 14
9pub(super) fn expr(p: &mut Parser) -> BlockLike { 15pub(super) fn expr(p: &mut Parser) -> BlockLike {
@@ -48,7 +54,7 @@ fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
48 } 54 }
49} 55}
50 56
51pub(super) fn stmt(p: &mut Parser, with_semi: bool) { 57pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
52 // test block_items 58 // test block_items
53 // fn a() { fn b() {} } 59 // fn a() { fn b() {} }
54 let m = p.start(); 60 let m = p.start();
@@ -111,13 +117,23 @@ pub(super) fn stmt(p: &mut Parser, with_semi: bool) {
111 // } 117 // }
112 // test!{} 118 // test!{}
113 // } 119 // }
114 if with_semi { 120
115 if blocklike.is_block() { 121 match with_semi {
116 p.eat(SEMI); 122 StmtWithSemi::Yes => {
117 } else { 123 if blocklike.is_block() {
118 p.expect(SEMI); 124 p.eat(SEMI);
125 } else {
126 p.expect(SEMI);
127 }
128 }
129 StmtWithSemi::No => {}
130 StmtWithSemi::Optional => {
131 if p.at(SEMI) {
132 p.eat(SEMI);
133 }
119 } 134 }
120 } 135 }
136
121 m.complete(p, EXPR_STMT); 137 m.complete(p, EXPR_STMT);
122 } 138 }
123 139
@@ -128,7 +144,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: bool) {
128 // let c = 92; 144 // let c = 92;
129 // let d: i32 = 92; 145 // let d: i32 = 92;
130 // } 146 // }
131 fn let_stmt(p: &mut Parser, m: Marker, with_semi: bool) { 147 fn let_stmt(p: &mut Parser, m: Marker, with_semi: StmtWithSemi) {
132 assert!(p.at(LET_KW)); 148 assert!(p.at(LET_KW));
133 p.bump(); 149 p.bump();
134 patterns::pattern(p); 150 patterns::pattern(p);
@@ -139,8 +155,16 @@ pub(super) fn stmt(p: &mut Parser, with_semi: bool) {
139 expressions::expr(p); 155 expressions::expr(p);
140 } 156 }
141 157
142 if with_semi { 158 match with_semi {
143 p.expect(SEMI); 159 StmtWithSemi::Yes => {
160 p.expect(SEMI);
161 }
162 StmtWithSemi::No => {}
163 StmtWithSemi::Optional => {
164 if p.at(SEMI) {
165 p.eat(SEMI);
166 }
167 }
144 } 168 }
145 m.complete(p, LET_STMT); 169 m.complete(p, LET_STMT);
146 } 170 }
@@ -160,7 +184,7 @@ pub(crate) fn expr_block_contents(p: &mut Parser) {
160 continue; 184 continue;
161 } 185 }
162 186
163 stmt(p, true) 187 stmt(p, StmtWithSemi::Yes)
164 } 188 }
165} 189}
166 190
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs
index 11b5b9a75..970d699c0 100644
--- a/crates/ra_parser/src/lib.rs
+++ b/crates/ra_parser/src/lib.rs
@@ -93,11 +93,35 @@ pub fn parse_stmt(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink,
93 parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi)); 93 parse_from_tokens(token_source, tree_sink, |p| grammar::stmt(p, with_semi));
94} 94}
95 95
96/// Parse given tokens into the given sink as a block
97pub fn parse_block(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
98 parse_from_tokens(token_source, tree_sink, grammar::block);
99}
100
101pub fn parse_meta(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
102 parse_from_tokens(token_source, tree_sink, grammar::meta_item);
103}
104
96/// Parse given tokens into the given sink as an item 105/// Parse given tokens into the given sink as an item
97pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) { 106pub fn parse_item(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
98 parse_from_tokens(token_source, tree_sink, grammar::item); 107 parse_from_tokens(token_source, tree_sink, grammar::item);
99} 108}
100 109
110/// Parse given tokens into the given sink as an visibility qualifier
111pub fn parse_vis(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
112 parse_from_tokens(token_source, tree_sink, |p| {
113 grammar::opt_visibility(p);
114 });
115}
116
117pub fn parse_macro_items(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
118 parse_from_tokens(token_source, tree_sink, grammar::macro_items);
119}
120
121pub fn parse_macro_stmts(token_source: &dyn TokenSource, tree_sink: &mut dyn TreeSink) {
122 parse_from_tokens(token_source, tree_sink, grammar::macro_stmts);
123}
124
101/// A parsing function for a specific braced-block. 125/// A parsing function for a specific braced-block.
102pub struct Reparser(fn(&mut parser::Parser)); 126pub struct Reparser(fn(&mut parser::Parser));
103 127
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index 498b0e164..6f984aea1 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -233,6 +233,8 @@ pub enum SyntaxKind {
233 ARG_LIST, 233 ARG_LIST,
234 TYPE_BOUND, 234 TYPE_BOUND,
235 TYPE_BOUND_LIST, 235 TYPE_BOUND_LIST,
236 MACRO_ITEMS,
237 MACRO_STMTS,
236 // Technical kind so that we can cast from u16 safely 238 // Technical kind so that we can cast from u16 safely
237 #[doc(hidden)] 239 #[doc(hidden)]
238 __LAST, 240 __LAST,
@@ -592,6 +594,8 @@ impl SyntaxKind {
592 ARG_LIST => &SyntaxInfo { name: "ARG_LIST" }, 594 ARG_LIST => &SyntaxInfo { name: "ARG_LIST" },
593 TYPE_BOUND => &SyntaxInfo { name: "TYPE_BOUND" }, 595 TYPE_BOUND => &SyntaxInfo { name: "TYPE_BOUND" },
594 TYPE_BOUND_LIST => &SyntaxInfo { name: "TYPE_BOUND_LIST" }, 596 TYPE_BOUND_LIST => &SyntaxInfo { name: "TYPE_BOUND_LIST" },
597 MACRO_ITEMS => &SyntaxInfo { name: "MACRO_ITEMS" },
598 MACRO_STMTS => &SyntaxInfo { name: "MACRO_STMTS" },
595 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, 599 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
596 EOF => &SyntaxInfo { name: "EOF" }, 600 EOF => &SyntaxInfo { name: "EOF" },
597 __LAST => &SyntaxInfo { name: "__LAST" }, 601 __LAST => &SyntaxInfo { name: "__LAST" },