diff options
| author | Nick Cameron <ncameron@mozilla.com> | 2015-09-14 21:58:20 +1200 |
|---|---|---|
| committer | Nick Cameron <ncameron@mozilla.com> | 2015-09-16 10:57:06 +1200 |
| commit | e9f1b063295c48c97e239ce479b08f192a3eece4 (patch) | |
| tree | d0f72439a2b01ecdba8675bf82d37f92eeec7950 /src/libsyntax | |
| parent | d2e13e822a73e0ea46ae9e21afdd3155fc997f6d (diff) | |
| download | rust-e9f1b063295c48c97e239ce479b08f192a3eece4.tar.gz rust-e9f1b063295c48c97e239ce479b08f192a3eece4.zip | |
Use ast attributes every where (remove HIR attributes).
This could be a [breaking-change] if your lint or syntax extension (is that even possible?) uses HIR attributes or literals.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 660 |
1 files changed, 350 insertions, 310 deletions
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 555fdc1ff86..b00ff85051c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -54,8 +54,8 @@ impl PpAnn for NoAnn {} #[derive(Copy, Clone)] pub struct CurrentCommentAndLiteral { - cur_cmnt: usize, - cur_lit: usize, + pub cur_cmnt: usize, + pub cur_lit: usize, } pub struct State<'a> { @@ -450,43 +450,369 @@ fn needs_parentheses(expr: &ast::Expr) -> bool { } } -impl<'a> State<'a> { - pub fn ibox(&mut self, u: usize) -> io::Result<()> { - self.boxes.push(pp::Breaks::Inconsistent); - pp::ibox(&mut self.s, u) +pub trait PrintState<'a> { + fn writer(&mut self) -> &mut pp::Printer<'a>; + fn boxes(&mut self) -> &mut Vec<pp::Breaks>; + fn comments(&mut self) -> &mut Option<Vec<comments::Comment>>; + fn cur_cmnt_and_lit(&mut self) -> &mut CurrentCommentAndLiteral; + fn literals(&self) -> &Option<Vec<comments::Literal>>; + + fn word_space(&mut self, w: &str) -> io::Result<()> { + try!(word(self.writer(), w)); + space(self.writer()) } - pub fn end(&mut self) -> io::Result<()> { - self.boxes.pop().unwrap(); - pp::end(&mut self.s) + fn popen(&mut self) -> io::Result<()> { word(self.writer(), "(") } + + fn pclose(&mut self) -> io::Result<()> { word(self.writer(), ")") } + + fn is_begin(&mut self) -> bool { + match self.writer().last_token() { + pp::Token::Begin(_) => true, + _ => false, + } } - pub fn cbox(&mut self, u: usize) -> io::Result<()> { - self.boxes.push(pp::Breaks::Consistent); - pp::cbox(&mut self.s, u) + fn is_end(&mut self) -> bool { + match self.writer().last_token() { + pp::Token::End => true, + _ => false, + } + } + + // is this the beginning of a line? + fn is_bol(&mut self) -> bool { + self.writer().last_token().is_eof() || self.writer().last_token().is_hardbreak_tok() + } + + fn hardbreak_if_not_bol(&mut self) -> io::Result<()> { + if !self.is_bol() { + try!(hardbreak(self.writer())) + } + Ok(()) } // "raw box" - pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> { - self.boxes.push(b); - pp::rbox(&mut self.s, u, b) + fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> { + self.boxes().push(b); + pp::rbox(self.writer(), u, b) } - pub fn nbsp(&mut self) -> io::Result<()> { word(&mut self.s, " ") } + fn ibox(&mut self, u: usize) -> io::Result<()> { + self.boxes().push(pp::Breaks::Inconsistent); + pp::ibox(self.writer(), u) + } - pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> { - try!(word(&mut self.s, w)); - self.nbsp() + fn end(&mut self) -> io::Result<()> { + self.boxes().pop().unwrap(); + pp::end(self.writer()) } - pub fn word_space(&mut self, w: &str) -> io::Result<()> { - try!(word(&mut self.s, w)); - space(&mut self.s) + fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> + where F: FnMut(&mut Self, &T) -> io::Result<()>, + { + try!(self.rbox(0, b)); + let mut first = true; + for elt in elts { + if first { first = false; } else { try!(self.word_space(",")); } + try!(op(self, elt)); + } + self.end() + } + + + fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> { + let mut cur_lit = self.cur_cmnt_and_lit().cur_lit; + + let mut result = None; + + if let &Some(ref lits) = self.literals() + { + while cur_lit < lits.len() { + let ltrl = (*lits)[cur_lit].clone(); + if ltrl.pos > pos { break; } + cur_lit += 1; + if ltrl.pos == pos { + result = Some(ltrl); + break; + } + } + } + + self.cur_cmnt_and_lit().cur_lit = cur_lit; + result + } + + fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> { + loop { + match self.next_comment() { + Some(ref cmnt) => { + if (*cmnt).pos < pos { + try!(self.print_comment(cmnt)); + self.cur_cmnt_and_lit().cur_cmnt += 1; + } else { break; } + } + _ => break + } + } + Ok(()) + } + + fn print_comment(&mut self, + cmnt: &comments::Comment) -> io::Result<()> { + match cmnt.style { + comments::Mixed => { + assert_eq!(cmnt.lines.len(), 1); + try!(zerobreak(self.writer())); + try!(word(self.writer(), &cmnt.lines[0])); + zerobreak(self.writer()) + } + comments::Isolated => { + try!(self.hardbreak_if_not_bol()); + for line in &cmnt.lines { + // Don't print empty lines because they will end up as trailing + // whitespace + if !line.is_empty() { + try!(word(self.writer(), &line[..])); + } + try!(hardbreak(self.writer())); + } + Ok(()) + } + comments::Trailing => { + try!(word(self.writer(), " ")); + if cmnt.lines.len() == 1 { + try!(word(self.writer(), &cmnt.lines[0])); + hardbreak(self.writer()) + } else { + try!(self.ibox(0)); + for line in &cmnt.lines { + if !line.is_empty() { + try!(word(self.writer(), &line[..])); + } + try!(hardbreak(self.writer())); + } + self.end() + } + } + comments::BlankLine => { + // We need to do at least one, possibly two hardbreaks. + let is_semi = match self.writer().last_token() { + pp::Token::String(s, _) => ";" == s, + _ => false + }; + if is_semi || self.is_begin() || self.is_end() { + try!(hardbreak(self.writer())); + } + hardbreak(self.writer()) + } + } + } + + fn next_comment(&mut self) -> Option<comments::Comment> { + let cur_cmnt = self.cur_cmnt_and_lit().cur_cmnt; + match *self.comments() { + Some(ref cmnts) => { + if cur_cmnt < cmnts.len() { + Some(cmnts[cur_cmnt].clone()) + } else { + None + } + } + _ => None + } + } + + fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> { + try!(self.maybe_print_comment(lit.span.lo)); + match self.next_lit(lit.span.lo) { + Some(ref ltrl) => { + return word(self.writer(), &(*ltrl).lit); + } + _ => () + } + match lit.node { + ast::LitStr(ref st, style) => self.print_string(&st, style), + ast::LitByte(byte) => { + let mut res = String::from("b'"); + res.extend(ascii::escape_default(byte).map(|c| c as char)); + res.push('\''); + word(self.writer(), &res[..]) + } + ast::LitChar(ch) => { + let mut res = String::from("'"); + res.extend(ch.escape_default()); + res.push('\''); + word(self.writer(), &res[..]) + } + ast::LitInt(i, t) => { + match t { + ast::SignedIntLit(st, ast::Plus) => { + word(self.writer(), + &ast_util::int_ty_to_string(st, Some(i as i64))) + } + ast::SignedIntLit(st, ast::Minus) => { + let istr = ast_util::int_ty_to_string(st, Some(-(i as i64))); + word(self.writer(), + &format!("-{}", istr)) + } + ast::UnsignedIntLit(ut) => { + word(self.writer(), &ast_util::uint_ty_to_string(ut, Some(i))) + } + ast::UnsuffixedIntLit(ast::Plus) => { + word(self.writer(), &format!("{}", i)) + } + ast::UnsuffixedIntLit(ast::Minus) => { + word(self.writer(), &format!("-{}", i)) + } + } + } + ast::LitFloat(ref f, t) => { + word(self.writer(), + &format!( + "{}{}", + &f, + &ast_util::float_ty_to_string(t))) + } + ast::LitFloatUnsuffixed(ref f) => word(self.writer(), &f[..]), + ast::LitBool(val) => { + if val { word(self.writer(), "true") } else { word(self.writer(), "false") } + } + ast::LitByteStr(ref v) => { + let mut escaped: String = String::new(); + for &ch in v.iter() { + escaped.extend(ascii::escape_default(ch) + .map(|c| c as char)); + } + word(self.writer(), &format!("b\"{}\"", escaped)) + } + } + } + + fn print_string(&mut self, st: &str, + style: ast::StrStyle) -> io::Result<()> { + let st = match style { + ast::CookedStr => { + (format!("\"{}\"", st.escape_default())) + } + ast::RawStr(n) => { + (format!("r{delim}\"{string}\"{delim}", + delim=repeat("#", n), + string=st)) + } + }; + word(self.writer(), &st[..]) + } + + fn print_inner_attributes(&mut self, + attrs: &[ast::Attribute]) -> io::Result<()> { + let mut count = 0; + for attr in attrs { + match attr.node.style { + ast::AttrInner => { + try!(self.print_attribute(attr)); + count += 1; + } + _ => {/* fallthrough */ } + } + } + if count > 0 { + try!(self.hardbreak_if_not_bol()); + } + Ok(()) + } + + fn print_outer_attributes(&mut self, + attrs: &[ast::Attribute]) -> io::Result<()> { + let mut count = 0; + for attr in attrs { + match attr.node.style { + ast::AttrOuter => { + try!(self.print_attribute(attr)); + count += 1; + } + _ => {/* fallthrough */ } + } + } + if count > 0 { + try!(self.hardbreak_if_not_bol()); + } + Ok(()) + } + + fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> { + try!(self.hardbreak_if_not_bol()); + try!(self.maybe_print_comment(attr.span.lo)); + if attr.node.is_sugared_doc { + word(self.writer(), &attr.value_str().unwrap()) + } else { + match attr.node.style { + ast::AttrInner => try!(word(self.writer(), "#![")), + ast::AttrOuter => try!(word(self.writer(), "#[")), + } + try!(self.print_meta_item(&*attr.meta())); + word(self.writer(), "]") + } + } + + fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> { + try!(self.ibox(indent_unit)); + match item.node { + ast::MetaWord(ref name) => { + try!(word(self.writer(), &name)); + } + ast::MetaNameValue(ref name, ref value) => { + try!(self.word_space(&name[..])); + try!(self.word_space("=")); + try!(self.print_literal(value)); + } + ast::MetaList(ref name, ref items) => { + try!(word(self.writer(), &name)); + try!(self.popen()); + try!(self.commasep(Consistent, + &items[..], + |s, i| s.print_meta_item(&**i))); + try!(self.pclose()); + } + } + self.end() + } +} + +impl<'a> PrintState<'a> for State<'a> { + fn writer(&mut self) -> &mut pp::Printer<'a> { + &mut self.s + } + + fn boxes(&mut self) -> &mut Vec<pp::Breaks> { + &mut self.boxes + } + + fn comments(&mut self) -> &mut Option<Vec<comments::Comment>> { + &mut self.comments + } + + fn cur_cmnt_and_lit(&mut self) -> &mut CurrentCommentAndLiteral { + &mut self.cur_cmnt_and_lit } - pub fn popen(&mut self) -> io::Result<()> { word(&mut self.s, "(") } + fn literals(&self) -> &Option<Vec<comments::Literal>> { + &self.literals + } +} - pub fn pclose(&mut self) -> io::Result<()> { word(&mut self.s, ")") } +impl<'a> State<'a> { + pub fn cbox(&mut self, u: usize) -> io::Result<()> { + self.boxes.push(pp::Breaks::Consistent); + pp::cbox(&mut self.s, u) + } + + pub fn nbsp(&mut self) -> io::Result<()> { word(&mut self.s, " ") } + + pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> { + try!(word(&mut self.s, w)); + self.nbsp() + } pub fn head(&mut self, w: &str) -> io::Result<()> { // outer-box is consistent @@ -523,25 +849,6 @@ impl<'a> State<'a> { self.bclose_(span, indent_unit) } - pub fn is_begin(&mut self) -> bool { - match self.s.last_token() { - pp::Token::Begin(_) => true, - _ => false, - } - } - - pub fn is_end(&mut self) -> bool { - match self.s.last_token() { - pp::Token::End => true, - _ => false, - } - } - - // is this the beginning of a line? - pub fn is_bol(&mut self) -> bool { - self.s.last_token().is_eof() || self.s.last_token().is_hardbreak_tok() - } - pub fn in_cbox(&self) -> bool { match self.boxes.last() { Some(&last_box) => last_box == pp::Breaks::Consistent, @@ -549,12 +856,6 @@ impl<'a> State<'a> { } } - pub fn hardbreak_if_not_bol(&mut self) -> io::Result<()> { - if !self.is_bol() { - try!(hardbreak(&mut self.s)) - } - Ok(()) - } pub fn space_if_not_bol(&mut self) -> io::Result<()> { if !self.is_bol() { try!(space(&mut self.s)); } Ok(()) @@ -584,17 +885,6 @@ impl<'a> State<'a> { word(&mut self.s, "*/") } - pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> where - F: FnMut(&mut State, &T) -> io::Result<()>, - { - try!(self.rbox(0, b)); - let mut first = true; - for elt in elts { - if first { first = false; } else { try!(self.word_space(",")); } - try!(op(self, elt)); - } - self.end() - } pub fn commasep_cmnt<T, F, G>(&mut self, @@ -1326,58 +1616,6 @@ impl<'a> State<'a> { self.ann.post(self, NodeSubItem(ii.id)) } - pub fn print_outer_attributes(&mut self, - attrs: &[ast::Attribute]) -> io::Result<()> { - let mut count = 0; - for attr in attrs { - match attr.node.style { - ast::AttrOuter => { - try!(self.print_attribute(attr)); - count += 1; - } - _ => {/* fallthrough */ } - } - } - if count > 0 { - try!(self.hardbreak_if_not_bol()); - } - Ok(()) - } - - pub fn print_inner_attributes(&mut self, - attrs: &[ast::Attribute]) -> io::Result<()> { - let mut count = 0; - for attr in attrs { - match attr.node.style { - ast::AttrInner => { - try!(self.print_attribute(attr)); - count += 1; - } - _ => {/* fallthrough */ } - } - } - if count > 0 { - try!(self.hardbreak_if_not_bol()); - } - Ok(()) - } - - pub fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> { - try!(self.hardbreak_if_not_bol()); - try!(self.maybe_print_comment(attr.span.lo)); - if attr.node.is_sugared_doc { - word(&mut self.s, &attr.value_str().unwrap()) - } else { - match attr.node.style { - ast::AttrInner => try!(word(&mut self.s, "#![")), - ast::AttrOuter => try!(word(&mut self.s, "#[")), - } - try!(self.print_meta_item(&*attr.meta())); - word(&mut self.s, "]") - } - } - - pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> { try!(self.maybe_print_comment(st.span.lo)); match st.node { @@ -2620,29 +2858,6 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> { - try!(self.ibox(indent_unit)); - match item.node { - ast::MetaWord(ref name) => { - try!(word(&mut self.s, &name)); - } - ast::MetaNameValue(ref name, ref value) => { - try!(self.word_space(&name[..])); - try!(self.word_space("=")); - try!(self.print_literal(value)); - } - ast::MetaList(ref name, ref items) => { - try!(word(&mut self.s, &name)); - try!(self.popen()); - try!(self.commasep(Consistent, - &items[..], - |s, i| s.print_meta_item(&**i))); - try!(self.pclose()); - } - } - self.end() - } - pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> { match vp.node { ast::ViewPathSimple(ident, ref path) => { @@ -2832,181 +3047,6 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> { - try!(self.maybe_print_comment(lit.span.lo)); - match self.next_lit(lit.span.lo) { - Some(ref ltrl) => { - return word(&mut self.s, &(*ltrl).lit); - } - _ => () - } - match lit.node { - ast::LitStr(ref st, style) => self.print_string(&st, style), - ast::LitByte(byte) => { - let mut res = String::from("b'"); - res.extend(ascii::escape_default(byte).map(|c| c as char)); - res.push('\''); - word(&mut self.s, &res[..]) - } - ast::LitChar(ch) => { - let mut res = String::from("'"); - res.extend(ch.escape_default()); - res.push('\''); - word(&mut self.s, &res[..]) - } - ast::LitInt(i, t) => { - match t { - ast::SignedIntLit(st, ast::Plus) => { - word(&mut self.s, - &ast_util::int_ty_to_string(st, Some(i as i64))) - } - ast::SignedIntLit(st, ast::Minus) => { - let istr = ast_util::int_ty_to_string(st, Some(-(i as i64))); - word(&mut self.s, - &format!("-{}", istr)) - } - ast::UnsignedIntLit(ut) => { - word(&mut self.s, &ast_util::uint_ty_to_string(ut, Some(i))) - } - ast::UnsuffixedIntLit(ast::Plus) => { - word(&mut self.s, &format!("{}", i)) - } - ast::UnsuffixedIntLit(ast::Minus) => { - word(&mut self.s, &format!("-{}", i)) - } - } - } - ast::LitFloat(ref f, t) => { - word(&mut self.s, - &format!( - "{}{}", - &f, - &ast_util::float_ty_to_string(t))) - } - ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[..]), - ast::LitBool(val) => { - if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") } - } - ast::LitByteStr(ref v) => { - let mut escaped: String = String::new(); - for &ch in v.iter() { - escaped.extend(ascii::escape_default(ch) - .map(|c| c as char)); - } - word(&mut self.s, &format!("b\"{}\"", escaped)) - } - } - } - - pub fn next_lit(&mut self, pos: BytePos) -> Option<comments::Literal> { - match self.literals { - Some(ref lits) => { - while self.cur_cmnt_and_lit.cur_lit < lits.len() { - let ltrl = (*lits)[self.cur_cmnt_and_lit.cur_lit].clone(); - if ltrl.pos > pos { return None; } - self.cur_cmnt_and_lit.cur_lit += 1; - if ltrl.pos == pos { return Some(ltrl); } - } - None - } - _ => None - } - } - - pub fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> { - loop { - match self.next_comment() { - Some(ref cmnt) => { - if (*cmnt).pos < pos { - try!(self.print_comment(cmnt)); - self.cur_cmnt_and_lit.cur_cmnt += 1; - } else { break; } - } - _ => break - } - } - Ok(()) - } - - pub fn print_comment(&mut self, - cmnt: &comments::Comment) -> io::Result<()> { - match cmnt.style { - comments::Mixed => { - assert_eq!(cmnt.lines.len(), 1); - try!(zerobreak(&mut self.s)); - try!(word(&mut self.s, &cmnt.lines[0])); - zerobreak(&mut self.s) - } - comments::Isolated => { - try!(self.hardbreak_if_not_bol()); - for line in &cmnt.lines { - // Don't print empty lines because they will end up as trailing - // whitespace - if !line.is_empty() { - try!(word(&mut self.s, &line[..])); - } - try!(hardbreak(&mut self.s)); - } - Ok(()) - } - comments::Trailing => { - try!(word(&mut self.s, " ")); - if cmnt.lines.len() == 1 { - try!(word(&mut self.s, &cmnt.lines[0])); - hardbreak(&mut self.s) - } else { - try!(self.ibox(0)); - for line in &cmnt.lines { - if !line.is_empty() { - try!(word(&mut self.s, &line[..])); - } - try!(hardbreak(&mut self.s)); - } - self.end() - } - } - comments::BlankLine => { - // We need to do at least one, possibly two hardbreaks. - let is_semi = match self.s.last_token() { - pp::Token::String(s, _) => ";" == s, - _ => false - }; - if is_semi || self.is_begin() || self.is_end() { - try!(hardbreak(&mut self.s)); - } - hardbreak(&mut self.s) - } - } - } - - pub fn print_string(&mut self, st: &str, - style: ast::StrStyle) -> io::Result<()> { - let st = match style { - ast::CookedStr => { - (format!("\"{}\"", st.escape_default())) - } - ast::RawStr(n) => { - (format!("r{delim}\"{string}\"{delim}", - delim=repeat("#", n), - string=st)) - } - }; - word(&mut self.s, &st[..]) - } - - pub fn next_comment(&mut self) -> Option<comments::Comment> { - match self.comments { - Some(ref cmnts) => { - if self.cur_cmnt_and_lit.cur_cmnt < cmnts.len() { - Some(cmnts[self.cur_cmnt_and_lit.cur_cmnt].clone()) - } else { - None - } - } - _ => None - } - } - pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option<abi::Abi>) -> io::Result<()> { |
