@@ -18,8 +18,7 @@ use std::path::Path;
18
18
19
19
use syntax:: ast;
20
20
use syntax:: parse:: lexer:: { self , Reader , StringReader } ;
21
- use syntax:: parse:: token:: { self , Token } ;
22
- use syntax:: symbol:: keywords;
21
+ use syntax:: tokenstream:: TokenTree ;
23
22
use syntax_pos:: * ;
24
23
25
24
#[ derive( Clone ) ]
@@ -87,6 +86,12 @@ impl<'a> SpanUtils<'a> {
87
86
lexer:: StringReader :: new ( s. diagnostic ( ) , filemap)
88
87
}
89
88
89
+ fn span_to_tts ( & self , span : Span ) -> Vec < TokenTree > {
90
+ let srdr = self . retokenise_span ( span) ;
91
+ let mut p = Parser :: new ( & self . sess . parse_sess , Box :: new ( srdr) ) ;
92
+ p. parse_all_token_trees ( ) . expect ( "Couldn't re-parse span" )
93
+ }
94
+
90
95
// Re-parses a path and returns the span for the last identifier in the path
91
96
pub fn span_for_last_ident ( & self , span : Span ) -> Option < Span > {
92
97
let mut result = None ;
@@ -308,6 +313,42 @@ impl<'a> SpanUtils<'a> {
308
313
}
309
314
}
310
315
316
+ /// `span` must be the span for an item such as a function or struct. This
317
+ /// function returns the program text from the start of the span until the
318
+ /// end of the 'signature' part, that is up to, but not including an opening
319
+ /// brace or semicolon.
320
+ pub fn signature_string_for_span ( & self , span : Span ) -> Option < String > {
321
+ let mut toks = self . span_to_tts ( span) . into_iter ( ) ;
322
+ let mut prev = toks. next ( ) . unwrap ( ) ;
323
+ let first_span = prev. get_span ( ) ;
324
+ let mut angle_count = 0 ;
325
+ for tok in toks {
326
+ if let TokenTree :: Token ( _, ref tok) = prev {
327
+ angle_count += match * tok {
328
+ token:: Eof => { return None ; }
329
+ token:: Lt => 1 ,
330
+ token:: Gt => -1 ,
331
+ token:: BinOp ( token:: Shl ) => 2 ,
332
+ token:: BinOp ( token:: Shr ) => -2 ,
333
+ _ => 0 ,
334
+ } ;
335
+ }
336
+ if angle_count > 0 {
337
+ prev = tok;
338
+ continue ;
339
+ }
340
+ if let TokenTree :: Token ( _, token:: Semi ) = tok {
341
+ return Some ( self . snippet ( mk_sp ( first_span. lo , prev. get_span ( ) . hi ) ) ) ;
342
+ } else if let TokenTree :: Delimited ( _, ref d) = tok {
343
+ if d. delim == token:: Brace {
344
+ return Some ( self . snippet ( mk_sp ( first_span. lo , prev. get_span ( ) . hi ) ) ) ;
345
+ }
346
+ }
347
+ prev = tok;
348
+ }
349
+ None
350
+ }
351
+
311
352
pub fn sub_span_before_token ( & self , span : Span , tok : Token ) -> Option < Span > {
312
353
let mut toks = self . retokenise_span ( span) ;
313
354
let mut prev = toks. real_token ( ) ;
0 commit comments