}
// Return the span for the last ident before a `<` and outside any
- // brackets, or the last span.
+ // angle brackets, or the last span.
pub fn sub_span_for_type_name(&self, span: Span) -> Option<Span> {
let mut toks = self.retokenise_span(span);
let mut prev = toks.real_token();
let mut result = None;
+
+ // We keep track of the following two counts - the depth of nesting of
+ // angle brackets, and the depth of nesting of square brackets. For the
+ // angle bracket count, we only count tokens which occur outside of any
+ // square brackets (i.e. bracket_count == 0). The intutition here is
+ // that we want to count angle brackets in the type, but not any which
+ // could be in expression context (because these could mean 'less than',
+ // etc.).
+ let mut angle_count = 0;
let mut bracket_count = 0;
loop {
let next = toks.real_token();
- if (next.tok == token::Lt || next.tok == token::Colon) && bracket_count == 0 &&
+ if (next.tok == token::Lt || next.tok == token::Colon) &&
+ angle_count == 0 &&
+ bracket_count == 0 &&
prev.tok.is_ident() {
result = Some(prev.sp);
}
+ if bracket_count == 0 {
+ angle_count += match prev.tok {
+ token::Lt => 1,
+ token::Gt => -1,
+ token::BinOp(token::Shl) => 2,
+ token::BinOp(token::Shr) => -2,
+ _ => 0,
+ };
+ }
+
bracket_count += match prev.tok {
- token::Lt => 1,
- token::Gt => -1,
- token::BinOp(token::Shl) => 2,
- token::BinOp(token::Shr) => -2,
+ token::OpenDelim(token::Bracket) => 1,
+ token::CloseDelim(token::Bracket) => -1,
_ => 0,
};
}
prev = next;
}
- if bracket_count != 0 {
+ if angle_count != 0 || bracket_count != 0 {
let loc = self.sess.codemap().lookup_char_pos(span.lo);
span_bug!(span,
"Mis-counted brackets when breaking path? Parsing '{}' \
loc.file.name,
loc.line);
}
- if result.is_none() && prev.tok.is_ident() && bracket_count == 0 {
+ if result.is_none() && prev.tok.is_ident() && angle_count == 0 {
return self.make_sub_span(span, Some(prev.sp));
}
self.make_sub_span(span, result)
// Reparse span and return an owned vector of sub spans of the first limit
// identifier tokens in the given nesting level.
// example with Foo<Bar<T,V>, Bar<T,V>>
- // Nesting = 0: all idents outside of brackets: [Foo]
- // Nesting = 1: idents within one level of brackets: [Bar, Bar]
+ // Nesting = 0: all idents outside of angle brackets: [Foo]
+ // Nesting = 1: idents within one level of angle brackets: [Bar, Bar]
pub fn spans_with_brackets(&self, span: Span, nesting: isize, limit: isize) -> Vec<Span> {
let mut result: Vec<Span> = vec![];
let mut toks = self.retokenise_span(span);
// We keep track of how many brackets we're nested in
+ let mut angle_count: isize = 0;
let mut bracket_count: isize = 0;
let mut found_ufcs_sep = false;
loop {
let ts = toks.real_token();
if ts.tok == token::Eof {
- if bracket_count != 0 {
+ if angle_count != 0 || bracket_count != 0 {
if generated_code(span) {
return vec![];
}
return result;
}
bracket_count += match ts.tok {
+ token::OpenDelim(token::Bracket) => 1,
+ token::CloseDelim(token::Bracket) => -1,
+ _ => 0,
+ };
+ if bracket_count > 0 {
+ continue;
+ }
+ angle_count += match ts.tok {
token::Lt => 1,
token::Gt => -1,
token::BinOp(token::Shl) => 2,
// path, trying to pull out the non-nested idents (e.g., avoiding 'a
// in `<A as B<'a>>::C`). So we end up with a span for `B>::C` from
// the start of the first ident to the end of the path.
- if !found_ufcs_sep && bracket_count == -1 {
+ if !found_ufcs_sep && angle_count == -1 {
found_ufcs_sep = true;
- bracket_count += 1;
+ angle_count += 1;
}
- if ts.tok.is_ident() && bracket_count == nesting {
+ if ts.tok.is_ident() && angle_count == nesting {
result.push(self.make_sub_span(span, Some(ts.sp)).unwrap());
}
}