1
+ use syntax_pos:: Span ;
2
+
1
3
use crate :: print:: pprust:: token_to_string;
2
4
use crate :: parse:: lexer:: { StringReader , UnmatchedBrace } ;
3
5
use crate :: parse:: { token, PResult } ;
4
6
use crate :: tokenstream:: { DelimSpan , IsJoint :: * , TokenStream , TokenTree , TreeAndJoint } ;
5
7
6
8
impl < ' a > StringReader < ' a > {
9
+ crate fn into_token_trees ( self ) -> ( PResult < ' a , TokenStream > , Vec < UnmatchedBrace > ) {
10
+ let mut tt_reader = TokenTreesReader {
11
+ string_reader : self ,
12
+ token : token:: Eof ,
13
+ span : syntax_pos:: DUMMY_SP ,
14
+ open_braces : Vec :: new ( ) ,
15
+ unmatched_braces : Vec :: new ( ) ,
16
+ matching_delim_spans : Vec :: new ( ) ,
17
+ last_unclosed_found_span : None ,
18
+ } ;
19
+ let res = tt_reader. parse_all_token_trees ( ) ;
20
+ ( res, tt_reader. unmatched_braces )
21
+ }
22
+ }
23
+
24
+ struct TokenTreesReader < ' a > {
25
+ string_reader : StringReader < ' a > ,
26
+ token : token:: Token ,
27
+ span : Span ,
28
+ /// Stack of open delimiters and their spans. Used for error message.
29
+ open_braces : Vec < ( token:: DelimToken , Span ) > ,
30
+ unmatched_braces : Vec < UnmatchedBrace > ,
31
+ /// The type and spans for all braces
32
+ ///
33
+ /// Used only for error recovery when arriving to EOF with mismatched braces.
34
+ matching_delim_spans : Vec < ( token:: DelimToken , Span , Span ) > ,
35
+ last_unclosed_found_span : Option < Span > ,
36
+ }
37
+
38
+ impl < ' a > TokenTreesReader < ' a > {
7
39
// Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`.
8
- crate fn parse_all_token_trees ( & mut self ) -> PResult < ' a , TokenStream > {
40
+ fn parse_all_token_trees ( & mut self ) -> PResult < ' a , TokenStream > {
9
41
let mut tts = Vec :: new ( ) ;
10
42
43
+ self . real_token ( ) ;
11
44
while self . token != token:: Eof {
12
45
tts. push ( self . parse_token_tree ( ) ?) ;
13
46
}
@@ -34,25 +67,25 @@ impl<'a> StringReader<'a> {
34
67
}
35
68
36
69
fn parse_token_tree ( & mut self ) -> PResult < ' a , TreeAndJoint > {
37
- let sm = self . sess . source_map ( ) ;
70
+ let sm = self . string_reader . sess . source_map ( ) ;
38
71
match self . token {
39
72
token:: Eof => {
40
73
let msg = "this file contains an un-closed delimiter" ;
41
- let mut err = self . sess . span_diagnostic . struct_span_err ( self . span , msg) ;
74
+ let mut err = self . string_reader . sess . span_diagnostic
75
+ . struct_span_err ( self . span , msg) ;
42
76
for & ( _, sp) in & self . open_braces {
43
77
err. span_label ( sp, "un-closed delimiter" ) ;
44
78
}
45
79
46
80
if let Some ( ( delim, _) ) = self . open_braces . last ( ) {
47
81
if let Some ( ( _, open_sp, close_sp) ) = self . matching_delim_spans . iter ( )
48
82
. filter ( |( d, open_sp, close_sp) | {
49
-
50
- if let Some ( close_padding ) = sm. span_to_margin ( * close_sp ) {
51
- if let Some ( open_padding ) = sm . span_to_margin ( * open_sp ) {
52
- return delim == d && close_padding != open_padding ;
83
+ if let Some ( close_padding ) = sm . span_to_margin ( * close_sp ) {
84
+ if let Some ( open_padding ) = sm. span_to_margin ( * open_sp ) {
85
+ return delim == d && close_padding != open_padding ;
86
+ }
53
87
}
54
- }
55
- false
88
+ false
56
89
} ) . next ( ) // these are in reverse order as they get inserted on close, but
57
90
{ // we want the last open/first close
58
91
err. span_label (
@@ -164,7 +197,8 @@ impl<'a> StringReader<'a> {
164
197
// matching opening delimiter).
165
198
let token_str = token_to_string ( & self . token ) ;
166
199
let msg = format ! ( "unexpected close delimiter: `{}`" , token_str) ;
167
- let mut err = self . sess . span_diagnostic . struct_span_err ( self . span , & msg) ;
200
+ let mut err = self . string_reader . sess . span_diagnostic
201
+ . struct_span_err ( self . span , & msg) ;
168
202
err. span_label ( self . span , "unexpected close delimiter" ) ;
169
203
Err ( err)
170
204
} ,
@@ -173,11 +207,20 @@ impl<'a> StringReader<'a> {
173
207
// Note that testing for joint-ness here is done via the raw
174
208
// source span as the joint-ness is a property of the raw source
175
209
// rather than wanting to take `override_span` into account.
176
- let raw = self . span_src_raw ;
210
+ // Additionally, we actually check if the *next* pair of tokens
211
+ // is joint, but this is equivalent to checking the current pair.
212
+ let raw = self . string_reader . peek_span_src_raw ;
177
213
self . real_token ( ) ;
178
- let is_joint = raw. hi ( ) == self . span_src_raw . lo ( ) && token:: is_op ( & self . token ) ;
214
+ let is_joint = raw. hi ( ) == self . string_reader . peek_span_src_raw . lo ( )
215
+ && token:: is_op ( & self . token ) ;
179
216
Ok ( ( tt, if is_joint { Joint } else { NonJoint } ) )
180
217
}
181
218
}
182
219
}
220
+
221
+ fn real_token ( & mut self ) {
222
+ let t = self . string_reader . real_token ( ) ;
223
+ self . token = t. tok ;
224
+ self . span = t. sp ;
225
+ }
183
226
}
0 commit comments