aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-05-27 08:28:13 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-05-27 08:28:13 +0100
commitce694ae11854a806031db98c51c068253f927519 (patch)
tree2996ecd85ff9aa57b6f208e83d42dd03a7370d1e /crates/ra_mbe
parent4f4e50db908ba44f113faeb356ae2b3d0788d308 (diff)
parent90764fc54b2be1e0fc5d6ac9c9e960d7bb059b14 (diff)
Merge #1328
1328: Change TokenSource to iteration based r=matklad a=edwin0cheng This PR change the `TokenSource` trait from random access to be an iteration based trait: ```rust /// `TokenSource` abstracts the source of the tokens parser operates one. /// /// Hopefully this will allow us to treat text and token trees in the same way! pub trait TokenSource { fn current(&self) -> Token; /// Lookahead n token fn lookahead_nth(&self, n: usize) -> Token; /// bump cursor to next token fn bump(&mut self); /// Is the current token a specified keyword? fn is_keyword(&self, kw: &str) -> bool; } /// `TokenCursor` abstracts the cursor of `TokenSource` operates one. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct Token { /// What is the current token? pub kind: SyntaxKind, /// Is the current token joined to the next one (`> >` vs `>>`). pub is_jointed_to_next: bool, } ``` Note that the refactoring based on this new trait will be separated to incoming PRs Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_mbe')
-rw-r--r--crates/ra_mbe/src/subtree_parser.rs4
-rw-r--r--crates/ra_mbe/src/subtree_source.rs59
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs63
3 files changed, 59 insertions, 67 deletions
diff --git a/crates/ra_mbe/src/subtree_parser.rs b/crates/ra_mbe/src/subtree_parser.rs
index 709b87a38..9cc989b23 100644
--- a/crates/ra_mbe/src/subtree_parser.rs
+++ b/crates/ra_mbe/src/subtree_parser.rs
@@ -68,13 +68,13 @@ impl<'a> Parser<'a> {
68 68
69 fn parse<F>(self, f: F) -> Option<tt::TokenTree> 69 fn parse<F>(self, f: F) -> Option<tt::TokenTree>
70 where 70 where
71 F: FnOnce(&dyn TokenSource, &mut dyn TreeSink), 71 F: FnOnce(&mut dyn TokenSource, &mut dyn TreeSink),
72 { 72 {
73 let buffer = TokenBuffer::new(&self.subtree.token_trees[*self.cur_pos..]); 73 let buffer = TokenBuffer::new(&self.subtree.token_trees[*self.cur_pos..]);
74 let mut src = SubtreeTokenSource::new(&buffer); 74 let mut src = SubtreeTokenSource::new(&buffer);
75 let mut sink = OffsetTokenSink { token_pos: 0, error: false }; 75 let mut sink = OffsetTokenSink { token_pos: 0, error: false };
76 76
77 f(&src, &mut sink); 77 f(&mut src, &mut sink);
78 78
79 let r = self.finish(sink.token_pos, &mut src); 79 let r = self.finish(sink.token_pos, &mut src);
80 if sink.error { 80 if sink.error {
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs
index 972af4a7c..c4f79f38a 100644
--- a/crates/ra_mbe/src/subtree_source.rs
+++ b/crates/ra_mbe/src/subtree_source.rs
@@ -1,6 +1,7 @@
1use ra_parser::{TokenSource}; 1use ra_parser::{TokenSource, Token};
2use ra_syntax::{classify_literal, SmolStr, SyntaxKind, SyntaxKind::*, T}; 2use ra_syntax::{classify_literal, SmolStr, SyntaxKind, SyntaxKind::*, T};
3use std::cell::{RefCell, Cell}; 3use std::cell::{RefCell, Cell};
4use std::sync::Arc;
4use tt::buffer::{TokenBuffer, Cursor}; 5use tt::buffer::{TokenBuffer, Cursor};
5 6
6pub(crate) trait Querier { 7pub(crate) trait Querier {
@@ -65,7 +66,7 @@ impl<'a> SubtreeWalk<'a> {
65 return cached[pos].clone(); 66 return cached[pos].clone();
66 } 67 }
67 68
68 fn collect_token_trees(&mut self, n: usize) -> Vec<tt::TokenTree> { 69 fn collect_token_trees(&self, n: usize) -> Vec<tt::TokenTree> {
69 let mut res = vec![]; 70 let mut res = vec![];
70 71
71 let mut pos = 0; 72 let mut pos = 0;
@@ -117,43 +118,59 @@ impl<'a> Querier for SubtreeWalk<'a> {
117} 118}
118 119
119pub(crate) struct SubtreeTokenSource<'a> { 120pub(crate) struct SubtreeTokenSource<'a> {
120 walker: SubtreeWalk<'a>, 121 walker: Arc<SubtreeWalk<'a>>,
122 curr: (Token, usize),
121} 123}
122 124
123impl<'a> SubtreeTokenSource<'a> { 125impl<'a> SubtreeTokenSource<'a> {
124 pub fn new(buffer: &'a TokenBuffer) -> SubtreeTokenSource<'a> { 126 pub fn new(buffer: &'a TokenBuffer) -> SubtreeTokenSource<'a> {
125 SubtreeTokenSource { walker: SubtreeWalk::new(buffer.begin()) } 127 let mut res = SubtreeTokenSource {
128 walker: Arc::new(SubtreeWalk::new(buffer.begin())),
129 curr: (Token { kind: EOF, is_jointed_to_next: false }, 0),
130 };
131 res.curr = (res.mk_token(0), 0);
132 res
126 } 133 }
127 134
128 pub fn querier<'b>(&'a self) -> &'b SubtreeWalk<'a> 135 pub fn querier(&self) -> Arc<SubtreeWalk<'a>> {
129 where 136 self.walker.clone()
130 'a: 'b,
131 {
132 &self.walker
133 } 137 }
134 138
135 pub(crate) fn bump_n(&mut self, parsed_tokens: usize) -> Vec<tt::TokenTree> { 139 pub(crate) fn bump_n(&mut self, parsed_tokens: usize) -> Vec<tt::TokenTree> {
136 let res = self.walker.collect_token_trees(parsed_tokens); 140 let res = self.walker.collect_token_trees(parsed_tokens);
137 res 141 res
138 } 142 }
143
144 fn mk_token(&self, pos: usize) -> Token {
145 match self.walker.get(pos) {
146 Some(tt) => Token { kind: tt.kind, is_jointed_to_next: tt.is_joint_to_next },
147 None => Token { kind: EOF, is_jointed_to_next: false },
148 }
149 }
139} 150}
140 151
141impl<'a> TokenSource for SubtreeTokenSource<'a> { 152impl<'a> TokenSource for SubtreeTokenSource<'a> {
142 fn token_kind(&self, pos: usize) -> SyntaxKind { 153 fn current(&self) -> Token {
143 if let Some(tok) = self.walker.get(pos) { 154 self.curr.0
144 tok.kind
145 } else {
146 SyntaxKind::EOF
147 }
148 } 155 }
149 fn is_token_joint_to_next(&self, pos: usize) -> bool { 156
150 match self.walker.get(pos) { 157 /// Lookahead n token
151 Some(t) => t.is_joint_to_next, 158 fn lookahead_nth(&self, n: usize) -> Token {
152 _ => false, 159 self.mk_token(self.curr.1 + n)
160 }
161
162 /// bump cursor to next token
163 fn bump(&mut self) {
164 if self.current().kind == EOF {
165 return;
153 } 166 }
167
168 self.curr = (self.mk_token(self.curr.1 + 1), self.curr.1 + 1)
154 } 169 }
155 fn is_keyword(&self, pos: usize, kw: &str) -> bool { 170
156 match self.walker.get(pos) { 171 /// Is the current token a specified keyword?
172 fn is_keyword(&self, kw: &str) -> bool {
173 match self.walker.get(self.curr.1) {
157 Some(t) => t.text == *kw, 174 Some(t) => t.text == *kw,
158 _ => false, 175 _ => false,
159 } 176 }
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index 0a75305b4..0a7e50c4e 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -45,17 +45,25 @@ pub fn syntax_node_to_token_tree(node: &SyntaxNode) -> Option<(tt::Subtree, Toke
45// 45//
46// 46//
47 47
48/// Parses the token tree (result of macro expansion) to an expression 48fn token_tree_to_syntax_node<F>(tt: &tt::Subtree, f: F) -> Result<TreeArc<SyntaxNode>, ExpandError>
49pub fn token_tree_to_expr(tt: &tt::Subtree) -> Result<TreeArc<ast::Expr>, ExpandError> { 49where
50 F: Fn(&mut ra_parser::TokenSource, &mut ra_parser::TreeSink),
51{
50 let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]); 52 let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]);
51 let token_source = SubtreeTokenSource::new(&buffer); 53 let mut token_source = SubtreeTokenSource::new(&buffer);
52 let mut tree_sink = TtTreeSink::new(token_source.querier()); 54 let querier = token_source.querier();
53 ra_parser::parse_expr(&token_source, &mut tree_sink); 55 let mut tree_sink = TtTreeSink::new(querier.as_ref());
56 f(&mut token_source, &mut tree_sink);
54 if tree_sink.roots.len() != 1 { 57 if tree_sink.roots.len() != 1 {
55 return Err(ExpandError::ConversionError); 58 return Err(ExpandError::ConversionError);
56 } 59 }
57 60
58 let syntax = tree_sink.inner.finish(); 61 Ok(tree_sink.inner.finish())
62}
63
64/// Parses the token tree (result of macro expansion) to an expression
65pub fn token_tree_to_expr(tt: &tt::Subtree) -> Result<TreeArc<ast::Expr>, ExpandError> {
66 let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_expr)?;
59 ast::Expr::cast(&syntax) 67 ast::Expr::cast(&syntax)
60 .map(|m| m.to_owned()) 68 .map(|m| m.to_owned())
61 .ok_or_else(|| crate::ExpandError::ConversionError) 69 .ok_or_else(|| crate::ExpandError::ConversionError)
@@ -63,28 +71,13 @@ pub fn token_tree_to_expr(tt: &tt::Subtree) -> Result<TreeArc<ast::Expr>, Expand
63 71
64/// Parses the token tree (result of macro expansion) to a Pattern 72/// Parses the token tree (result of macro expansion) to a Pattern
65pub fn token_tree_to_pat(tt: &tt::Subtree) -> Result<TreeArc<ast::Pat>, ExpandError> { 73pub fn token_tree_to_pat(tt: &tt::Subtree) -> Result<TreeArc<ast::Pat>, ExpandError> {
66 let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]); 74 let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_pat)?;
67 let token_source = SubtreeTokenSource::new(&buffer);
68 let mut tree_sink = TtTreeSink::new(token_source.querier());
69 ra_parser::parse_pat(&token_source, &mut tree_sink);
70 if tree_sink.roots.len() != 1 {
71 return Err(ExpandError::ConversionError);
72 }
73
74 let syntax = tree_sink.inner.finish();
75 ast::Pat::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError) 75 ast::Pat::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError)
76} 76}
77 77
78/// Parses the token tree (result of macro expansion) to a Type 78/// Parses the token tree (result of macro expansion) to a Type
79pub fn token_tree_to_ty(tt: &tt::Subtree) -> Result<TreeArc<ast::TypeRef>, ExpandError> { 79pub fn token_tree_to_ty(tt: &tt::Subtree) -> Result<TreeArc<ast::TypeRef>, ExpandError> {
80 let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]); 80 let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_ty)?;
81 let token_source = SubtreeTokenSource::new(&buffer);
82 let mut tree_sink = TtTreeSink::new(token_source.querier());
83 ra_parser::parse_ty(&token_source, &mut tree_sink);
84 if tree_sink.roots.len() != 1 {
85 return Err(ExpandError::ConversionError);
86 }
87 let syntax = tree_sink.inner.finish();
88 ast::TypeRef::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError) 81 ast::TypeRef::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError)
89} 82}
90 83
@@ -92,14 +85,7 @@ pub fn token_tree_to_ty(tt: &tt::Subtree) -> Result<TreeArc<ast::TypeRef>, Expan
92pub fn token_tree_to_macro_stmts( 85pub fn token_tree_to_macro_stmts(
93 tt: &tt::Subtree, 86 tt: &tt::Subtree,
94) -> Result<TreeArc<ast::MacroStmts>, ExpandError> { 87) -> Result<TreeArc<ast::MacroStmts>, ExpandError> {
95 let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]); 88 let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_macro_stmts)?;
96 let token_source = SubtreeTokenSource::new(&buffer);
97 let mut tree_sink = TtTreeSink::new(token_source.querier());
98 ra_parser::parse_macro_stmts(&token_source, &mut tree_sink);
99 if tree_sink.roots.len() != 1 {
100 return Err(ExpandError::ConversionError);
101 }
102 let syntax = tree_sink.inner.finish();
103 ast::MacroStmts::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError) 89 ast::MacroStmts::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError)
104} 90}
105 91
@@ -107,24 +93,13 @@ pub fn token_tree_to_macro_stmts(
107pub fn token_tree_to_macro_items( 93pub fn token_tree_to_macro_items(
108 tt: &tt::Subtree, 94 tt: &tt::Subtree,
109) -> Result<TreeArc<ast::MacroItems>, ExpandError> { 95) -> Result<TreeArc<ast::MacroItems>, ExpandError> {
110 let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]); 96 let syntax = token_tree_to_syntax_node(tt, ra_parser::parse_macro_items)?;
111 let token_source = SubtreeTokenSource::new(&buffer);
112 let mut tree_sink = TtTreeSink::new(token_source.querier());
113 ra_parser::parse_macro_items(&token_source, &mut tree_sink);
114 if tree_sink.roots.len() != 1 {
115 return Err(ExpandError::ConversionError);
116 }
117 let syntax = tree_sink.inner.finish();
118 ast::MacroItems::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError) 97 ast::MacroItems::cast(&syntax).map(|m| m.to_owned()).ok_or_else(|| ExpandError::ConversionError)
119} 98}
120 99
121/// Parses the token tree (result of macro expansion) as a sequence of items 100/// Parses the token tree (result of macro expansion) as a sequence of items
122pub fn token_tree_to_ast_item_list(tt: &tt::Subtree) -> TreeArc<ast::SourceFile> { 101pub fn token_tree_to_ast_item_list(tt: &tt::Subtree) -> TreeArc<ast::SourceFile> {
123 let buffer = tt::buffer::TokenBuffer::new(&[tt.clone().into()]); 102 let syntax = token_tree_to_syntax_node(tt, ra_parser::parse).unwrap();
124 let token_source = SubtreeTokenSource::new(&buffer);
125 let mut tree_sink = TtTreeSink::new(token_source.querier());
126 ra_parser::parse(&token_source, &mut tree_sink);
127 let syntax = tree_sink.inner.finish();
128 ast::SourceFile::cast(&syntax).unwrap().to_owned() 103 ast::SourceFile::cast(&syntax).unwrap().to_owned()
129} 104}
130 105