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
+ open_braces : Vec :: new ( ) ,
13
+ unmatched_braces : Vec :: new ( ) ,
14
+ matching_delim_spans : Vec :: new ( ) ,
15
+ last_unclosed_found_span : None ,
16
+ } ;
17
+ let res = tt_reader. parse_all_token_trees ( ) ;
18
+ ( res, tt_reader. unmatched_braces )
19
+ }
20
+ }
21
+
22
+ struct TokenTreesReader < ' a > {
23
+ string_reader : StringReader < ' a > ,
24
+ /// Stack of open delimiters and their spans. Used for error message.
25
+ open_braces : Vec < ( token:: DelimToken , Span ) > ,
26
+ unmatched_braces : Vec < UnmatchedBrace > ,
27
+ /// The type and spans for all braces
28
+ ///
29
+ /// Used only for error recovery when arriving to EOF with mismatched braces.
30
+ matching_delim_spans : Vec < ( token:: DelimToken , Span , Span ) > ,
31
+ last_unclosed_found_span : Option < Span > ,
32
+ }
33
+
34
+ impl < ' a > TokenTreesReader < ' a > {
7
35
// 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 > {
36
+ fn parse_all_token_trees ( & mut self ) -> PResult < ' a , TokenStream > {
9
37
let mut tts = Vec :: new ( ) ;
10
38
11
- while self . token != token:: Eof {
39
+ while self . string_reader . token != token:: Eof {
12
40
tts. push ( self . parse_token_tree ( ) ?) ;
13
41
}
14
42
@@ -19,7 +47,7 @@ impl<'a> StringReader<'a> {
19
47
fn parse_token_trees_until_close_delim ( & mut self ) -> TokenStream {
20
48
let mut tts = vec ! [ ] ;
21
49
loop {
22
- if let token:: CloseDelim ( ..) = self . token {
50
+ if let token:: CloseDelim ( ..) = self . string_reader . token {
23
51
return TokenStream :: new ( tts) ;
24
52
}
25
53
@@ -34,25 +62,25 @@ impl<'a> StringReader<'a> {
34
62
}
35
63
36
64
fn parse_token_tree ( & mut self ) -> PResult < ' a , TreeAndJoint > {
37
- let sm = self . sess . source_map ( ) ;
38
- match self . token {
65
+ let sm = self . string_reader . sess . source_map ( ) ;
66
+ match self . string_reader . token {
39
67
token:: Eof => {
40
68
let msg = "this file contains an un-closed delimiter" ;
41
- let mut err = self . sess . span_diagnostic . struct_span_err ( self . span , msg) ;
69
+ let mut err = self . string_reader . sess . span_diagnostic
70
+ . struct_span_err ( self . span ( ) , msg) ;
42
71
for & ( _, sp) in & self . open_braces {
43
72
err. span_label ( sp, "un-closed delimiter" ) ;
44
73
}
45
74
46
75
if let Some ( ( delim, _) ) = self . open_braces . last ( ) {
47
76
if let Some ( ( _, open_sp, close_sp) ) = self . matching_delim_spans . iter ( )
48
77
. 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 ;
78
+ if let Some ( close_padding ) = sm . span_to_margin ( * close_sp ) {
79
+ if let Some ( open_padding ) = sm. span_to_margin ( * open_sp ) {
80
+ return delim == d && close_padding != open_padding ;
81
+ }
53
82
}
54
- }
55
- false
83
+ false
56
84
} ) . next ( ) // these are in reverse order as they get inserted on close, but
57
85
{ // we want the last open/first close
58
86
err. span_label (
@@ -69,21 +97,21 @@ impl<'a> StringReader<'a> {
69
97
} ,
70
98
token:: OpenDelim ( delim) => {
71
99
// The span for beginning of the delimited section
72
- let pre_span = self . span ;
100
+ let pre_span = self . span ( ) ;
73
101
74
102
// Parse the open delimiter.
75
- self . open_braces . push ( ( delim, self . span ) ) ;
76
- self . real_token ( ) ;
103
+ self . open_braces . push ( ( delim, self . span ( ) ) ) ;
104
+ self . string_reader . real_token ( ) ;
77
105
78
106
// Parse the token trees within the delimiters.
79
107
// We stop at any delimiter so we can try to recover if the user
80
108
// uses an incorrect delimiter.
81
109
let tts = self . parse_token_trees_until_close_delim ( ) ;
82
110
83
111
// Expand to cover the entire delimited token tree
84
- let delim_span = DelimSpan :: from_pair ( pre_span, self . span ) ;
112
+ let delim_span = DelimSpan :: from_pair ( pre_span, self . span ( ) ) ;
85
113
86
- match self . token {
114
+ match self . string_reader . token {
87
115
// Correct delimiter.
88
116
token:: CloseDelim ( d) if d == delim => {
89
117
let ( open_brace, open_brace_span) = self . open_braces . pop ( ) . unwrap ( ) ;
@@ -93,26 +121,26 @@ impl<'a> StringReader<'a> {
93
121
self . matching_delim_spans . clear ( ) ;
94
122
} else {
95
123
self . matching_delim_spans . push (
96
- ( open_brace, open_brace_span, self . span ) ,
124
+ ( open_brace, open_brace_span, self . span ( ) ) ,
97
125
) ;
98
126
}
99
127
// Parse the close delimiter.
100
- self . real_token ( ) ;
128
+ self . string_reader . real_token ( ) ;
101
129
}
102
130
// Incorrect delimiter.
103
131
token:: CloseDelim ( other) => {
104
132
let mut unclosed_delimiter = None ;
105
133
let mut candidate = None ;
106
- if self . last_unclosed_found_span != Some ( self . span ) {
134
+ if self . last_unclosed_found_span != Some ( self . span ( ) ) {
107
135
// do not complain about the same unclosed delimiter multiple times
108
- self . last_unclosed_found_span = Some ( self . span ) ;
136
+ self . last_unclosed_found_span = Some ( self . span ( ) ) ;
109
137
// This is a conservative error: only report the last unclosed
110
138
// delimiter. The previous unclosed delimiters could actually be
111
139
// closed! The parser just hasn't gotten to them yet.
112
140
if let Some ( & ( _, sp) ) = self . open_braces . last ( ) {
113
141
unclosed_delimiter = Some ( sp) ;
114
142
} ;
115
- if let Some ( current_padding) = sm. span_to_margin ( self . span ) {
143
+ if let Some ( current_padding) = sm. span_to_margin ( self . span ( ) ) {
116
144
for ( brace, brace_span) in & self . open_braces {
117
145
if let Some ( padding) = sm. span_to_margin ( * brace_span) {
118
146
// high likelihood of these two corresponding
@@ -126,7 +154,7 @@ impl<'a> StringReader<'a> {
126
154
self . unmatched_braces . push ( UnmatchedBrace {
127
155
expected_delim : tok,
128
156
found_delim : other,
129
- found_span : self . span ,
157
+ found_span : self . span ( ) ,
130
158
unclosed_span : unclosed_delimiter,
131
159
candidate_span : candidate,
132
160
} ) ;
@@ -142,7 +170,7 @@ impl<'a> StringReader<'a> {
142
170
// bar(baz(
143
171
// } // Incorrect delimiter but matches the earlier `{`
144
172
if !self . open_braces . iter ( ) . any ( |& ( b, _) | b == other) {
145
- self . real_token ( ) ;
173
+ self . string_reader . real_token ( ) ;
146
174
}
147
175
}
148
176
token:: Eof => {
@@ -162,22 +190,28 @@ impl<'a> StringReader<'a> {
162
190
token:: CloseDelim ( _) => {
163
191
// An unexpected closing delimiter (i.e., there is no
164
192
// matching opening delimiter).
165
- let token_str = token_to_string ( & self . token ) ;
193
+ let token_str = token_to_string ( & self . string_reader . token ) ;
166
194
let msg = format ! ( "unexpected close delimiter: `{}`" , token_str) ;
167
- let mut err = self . sess . span_diagnostic . struct_span_err ( self . span , & msg) ;
168
- err. span_label ( self . span , "unexpected close delimiter" ) ;
195
+ let mut err = self . string_reader . sess . span_diagnostic
196
+ . struct_span_err ( self . span ( ) , & msg) ;
197
+ err. span_label ( self . span ( ) , "unexpected close delimiter" ) ;
169
198
Err ( err)
170
199
} ,
171
200
_ => {
172
- let tt = TokenTree :: Token ( self . span , self . token . clone ( ) ) ;
201
+ let tt = TokenTree :: Token ( self . span ( ) , self . string_reader . token . clone ( ) ) ;
173
202
// Note that testing for joint-ness here is done via the raw
174
203
// source span as the joint-ness is a property of the raw source
175
204
// rather than wanting to take `override_span` into account.
176
- let raw = self . span_src_raw ;
177
- self . real_token ( ) ;
178
- let is_joint = raw. hi ( ) == self . span_src_raw . lo ( ) && token:: is_op ( & self . token ) ;
205
+ let raw = self . string_reader . span_src_raw ;
206
+ self . string_reader . real_token ( ) ;
207
+ let is_joint = raw. hi ( ) == self . string_reader . span_src_raw . lo ( )
208
+ && token:: is_op ( & self . string_reader . token ) ;
179
209
Ok ( ( tt, if is_joint { Joint } else { NonJoint } ) )
180
210
}
181
211
}
182
212
}
213
+
214
+ fn span ( & self ) -> Span {
215
+ self . string_reader . span
216
+ }
183
217
}
0 commit comments