Skip to content

Commit 95593a6

Browse files
committed
syntax: support customization of literals in pretty-printing annotators.
1 parent fec2c12 commit 95593a6

File tree

2 files changed

+86
-85
lines changed

2 files changed

+86
-85
lines changed

src/libsyntax/ext/quote.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ pub mod rt {
199199
fn to_source(&self) -> String {
200200
let lit = dummy_spanned(ast::LitStr(
201201
token::intern_and_get_ident(self), ast::CookedStr));
202-
pprust::lit_to_string(&lit)
202+
pprust::lit_to_string(&lit).into_owned()
203203
}
204204
}
205205
impl ToSourceWithHygiene for str {
@@ -222,7 +222,7 @@ pub mod rt {
222222
impl ToSource for bool {
223223
fn to_source(&self) -> String {
224224
let lit = dummy_spanned(ast::LitBool(*self));
225-
pprust::lit_to_string(&lit)
225+
pprust::lit_to_string(&lit).into_owned()
226226
}
227227
}
228228
impl ToSourceWithHygiene for bool {
@@ -234,7 +234,7 @@ pub mod rt {
234234
impl ToSource for char {
235235
fn to_source(&self) -> String {
236236
let lit = dummy_spanned(ast::LitChar(*self));
237-
pprust::lit_to_string(&lit)
237+
pprust::lit_to_string(&lit).into_owned()
238238
}
239239
}
240240
impl ToSourceWithHygiene for char {
@@ -249,7 +249,7 @@ pub mod rt {
249249
fn to_source(&self) -> String {
250250
let lit = ast::LitInt(*self as u64, ast::SignedIntLit($tag,
251251
ast::Sign::new(*self)));
252-
pprust::lit_to_string(&dummy_spanned(lit))
252+
pprust::lit_to_string(&dummy_spanned(lit)).into_owned()
253253
}
254254
}
255255
impl ToSourceWithHygiene for $t {
@@ -262,7 +262,7 @@ pub mod rt {
262262
impl ToSource for $t {
263263
fn to_source(&self) -> String {
264264
let lit = ast::LitInt(*self as u64, ast::UnsignedIntLit($tag));
265-
pprust::lit_to_string(&dummy_spanned(lit))
265+
pprust::lit_to_string(&dummy_spanned(lit)).into_owned()
266266
}
267267
}
268268
impl ToSourceWithHygiene for $t {

src/libsyntax/print/pprust.rs

Lines changed: 81 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use ptr::P;
3030
use std_inject;
3131

3232
use std::{ascii, mem};
33+
use std::borrow::{Cow, IntoCow};
3334
use std::old_io::{self, IoResult};
3435
use std::iter;
3536

@@ -45,6 +46,9 @@ pub enum AnnNode<'a> {
4546
pub trait PpAnn {
4647
fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
4748
fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
49+
fn literal_to_string<'a>(&self, state: &mut State, lit: &'a ast::Lit) -> Cow<'a, str> {
50+
state.literal_to_string(lit)
51+
}
4852
}
4953

5054
#[derive(Copy)]
@@ -309,6 +313,73 @@ pub fn token_to_string(tok: &Token) -> String {
309313
}
310314
}
311315

316+
fn string_lit_to_string(st: &str, style: ast::StrStyle) -> String {
317+
match style {
318+
ast::CookedStr => {
319+
format!("\"{}\"", st.escape_default())
320+
}
321+
ast::RawStr(n) => {
322+
format!("r{delim}\"{string}\"{delim}",
323+
delim=repeat("#", n),
324+
string=st)
325+
}
326+
}
327+
}
328+
329+
pub fn lit_to_string<'a>(lit: &'a ast::Lit) -> Cow<'a, str> {
330+
match lit.node {
331+
ast::LitStr(ref st, style) => {
332+
string_lit_to_string(&st, style).into_cow()
333+
}
334+
ast::LitByte(byte) => {
335+
let mut res = String::from_str("b'");
336+
res.extend(ascii::escape_default(byte).map(|c| c as char));
337+
res.push('\'');
338+
res.into_cow()
339+
}
340+
ast::LitChar(ch) => {
341+
let mut res = String::from_str("'");
342+
res.extend(ch.escape_default());
343+
res.push('\'');
344+
res.into_cow()
345+
}
346+
ast::LitInt(i, t) => {
347+
match t {
348+
ast::SignedIntLit(st, ast::Plus) => {
349+
ast_util::int_ty_to_string(st, Some(i as i64))
350+
}
351+
ast::SignedIntLit(st, ast::Minus) => {
352+
let istr = ast_util::int_ty_to_string(st, Some(-(i as i64)));
353+
format!("-{}", istr)
354+
}
355+
ast::UnsignedIntLit(ut) => {
356+
ast_util::uint_ty_to_string(ut, Some(i))
357+
}
358+
ast::UnsuffixedIntLit(ast::Plus) => {
359+
format!("{}", i)
360+
}
361+
ast::UnsuffixedIntLit(ast::Minus) => {
362+
format!("-{}", i)
363+
}
364+
}.into_cow()
365+
}
366+
ast::LitFloat(ref f, t) => {
367+
format!("{}{}", f, &ast_util::float_ty_to_string(t)).into_cow()
368+
}
369+
ast::LitFloatUnsuffixed(ref f) => f.into_cow(),
370+
ast::LitBool(val) => {
371+
if val { "true" } else { "false" }.into_cow()
372+
}
373+
ast::LitBinary(ref v) => {
374+
let mut escaped: String = String::new();
375+
for &ch in &**v {
376+
escaped.extend(ascii::escape_default(ch as u8).map(|c| c as char));
377+
}
378+
format!("b\"{}\"", escaped).into_cow()
379+
}
380+
}
381+
}
382+
312383
// FIXME (Issue #16472): the thing_to_string_impls macro should go away
313384
// after we revise the syntax::ext::quote::ToToken impls to go directly
314385
// to token-trees instead of thing -> string -> token-trees.
@@ -409,10 +480,6 @@ pub fn attribute_to_string(attr: &ast::Attribute) -> String {
409480
$to_string(|s| s.print_attribute(attr))
410481
}
411482

412-
pub fn lit_to_string(l: &ast::Lit) -> String {
413-
$to_string(|s| s.print_literal(l))
414-
}
415-
416483
pub fn explicit_self_to_string(explicit_self: &ast::ExplicitSelf_) -> String {
417484
$to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
418485
}
@@ -1710,7 +1777,8 @@ impl<'a> State<'a> {
17101777
try!(self.print_expr_addr_of(m, &**expr));
17111778
}
17121779
ast::ExprLit(ref lit) => {
1713-
try!(self.print_literal(&**lit));
1780+
let s = self.ann.literal_to_string(self, lit);
1781+
try!(word(&mut self.s, &s));
17141782
}
17151783
ast::ExprCast(ref expr, ref ty) => {
17161784
try!(self.print_expr(&**expr));
@@ -2582,7 +2650,8 @@ impl<'a> State<'a> {
25822650
ast::MetaNameValue(ref name, ref value) => {
25832651
try!(self.word_space(&name[..]));
25842652
try!(self.word_space("="));
2585-
try!(self.print_literal(value));
2653+
let s = self.literal_to_string(value);
2654+
try!(word(&mut self.s, &s));
25862655
}
25872656
ast::MetaList(ref name, ref items) => {
25882657
try!(word(&mut self.s, &name));
@@ -2767,69 +2836,11 @@ impl<'a> State<'a> {
27672836
Ok(())
27682837
}
27692838

2770-
pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
2771-
try!(self.maybe_print_comment(lit.span.lo));
2772-
match self.next_lit(lit.span.lo) {
2773-
Some(ref ltrl) => {
2774-
return word(&mut self.s, &(*ltrl).lit);
2775-
}
2776-
_ => ()
2777-
}
2778-
match lit.node {
2779-
ast::LitStr(ref st, style) => self.print_string(&st, style),
2780-
ast::LitByte(byte) => {
2781-
let mut res = String::from_str("b'");
2782-
res.extend(ascii::escape_default(byte).map(|c| c as char));
2783-
res.push('\'');
2784-
word(&mut self.s, &res[..])
2785-
}
2786-
ast::LitChar(ch) => {
2787-
let mut res = String::from_str("'");
2788-
res.extend(ch.escape_default());
2789-
res.push('\'');
2790-
word(&mut self.s, &res[..])
2791-
}
2792-
ast::LitInt(i, t) => {
2793-
match t {
2794-
ast::SignedIntLit(st, ast::Plus) => {
2795-
word(&mut self.s,
2796-
&ast_util::int_ty_to_string(st, Some(i as i64)))
2797-
}
2798-
ast::SignedIntLit(st, ast::Minus) => {
2799-
let istr = ast_util::int_ty_to_string(st, Some(-(i as i64)));
2800-
word(&mut self.s,
2801-
&format!("-{}", istr))
2802-
}
2803-
ast::UnsignedIntLit(ut) => {
2804-
word(&mut self.s, &ast_util::uint_ty_to_string(ut, Some(i)))
2805-
}
2806-
ast::UnsuffixedIntLit(ast::Plus) => {
2807-
word(&mut self.s, &format!("{}", i))
2808-
}
2809-
ast::UnsuffixedIntLit(ast::Minus) => {
2810-
word(&mut self.s, &format!("-{}", i))
2811-
}
2812-
}
2813-
}
2814-
ast::LitFloat(ref f, t) => {
2815-
word(&mut self.s,
2816-
&format!(
2817-
"{}{}",
2818-
&f,
2819-
&ast_util::float_ty_to_string(t)))
2820-
}
2821-
ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, &f[..]),
2822-
ast::LitBool(val) => {
2823-
if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") }
2824-
}
2825-
ast::LitBinary(ref v) => {
2826-
let mut escaped: String = String::new();
2827-
for &ch in &**v {
2828-
escaped.extend(ascii::escape_default(ch as u8)
2829-
.map(|c| c as char));
2830-
}
2831-
word(&mut self.s, &format!("b\"{}\"", escaped))
2832-
}
2839+
pub fn literal_to_string<'b>(&mut self, lit: &'b ast::Lit) -> Cow<'b, str> {
2840+
if let Some(ltrl) = self.next_lit(lit.span.lo) {
2841+
ltrl.lit.into_cow()
2842+
} else {
2843+
lit_to_string(lit)
28332844
}
28342845
}
28352846

@@ -2916,17 +2927,7 @@ impl<'a> State<'a> {
29162927

29172928
pub fn print_string(&mut self, st: &str,
29182929
style: ast::StrStyle) -> IoResult<()> {
2919-
let st = match style {
2920-
ast::CookedStr => {
2921-
(format!("\"{}\"", st.escape_default()))
2922-
}
2923-
ast::RawStr(n) => {
2924-
(format!("r{delim}\"{string}\"{delim}",
2925-
delim=repeat("#", n),
2926-
string=st))
2927-
}
2928-
};
2929-
word(&mut self.s, &st[..])
2930+
word(&mut self.s, &string_lit_to_string(st, style))
29302931
}
29312932

29322933
pub fn next_comment(&mut self) -> Option<comments::Comment> {

0 commit comments

Comments
 (0)