diff options
| author | bors <bors@rust-lang.org> | 2013-03-27 21:51:53 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-03-27 21:51:53 -0700 |
| commit | 84ddff3909b5920228642649b7f5cc011c0b900a (patch) | |
| tree | 25cfe9b7ddd20bc08ea56de4fe87dbabf9a885f0 /src/libsyntax/ext | |
| parent | 4954d3e50177c46d260a5340ff91bfada8590ef0 (diff) | |
| parent | c317d3f6fa9475e65b6276743c09444441059ca7 (diff) | |
| download | rust-84ddff3909b5920228642649b7f5cc011c0b900a.tar.gz rust-84ddff3909b5920228642649b7f5cc011c0b900a.zip | |
auto merge of #5578 : erickt/rust/incoming, r=jbclements,erickt
Hey folks,
This patch series does some work on the json decoder, specifically with auto decoding of enums. Previously, we would take this code:
```
enum A {
B,
C(~str, uint)
}
```
and would encode a value of this enum to either `["B", []]` or `["C", ["D", 123]]`. I've changed this to `"B"` or `["C", "D", 123]`. This matches the style of the O'Caml json library [json-wheel](http://mjambon.com/json-wheel.html). I've added tests to make sure all this work.
In order to make this change, I added passing a `&[&str]` vec to `Decode::emit_enum_variant` so the json decoder can convert the name of a variant into it's position. I also changed the impl of `Encodable` for `Option<T>` to have the right upper casing.
I also did some work on the parser, which allows for `fn foo<T: ::cmp::Eq>() { ... }` statements (#5572), fixed the pretty printer properly expanding `debug!("...")` expressions, and removed `ast::expr_vstore_fixed`, which doesn't appear to be used anymore.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/auto_encode.rs | 96 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 167 |
3 files changed, 245 insertions, 23 deletions
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index e81e460e832..2a112f106a8 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -1059,6 +1059,18 @@ fn mk_enum_deser_body( name: ast::ident, variants: ~[ast::variant] ) -> @ast::expr { + let expr_arm_names = build::mk_base_vec_e( + ext_cx, + span, + do variants.map |variant| { + build::mk_base_str( + ext_cx, + span, + ext_cx.str_of(variant.node.name) + ) + } + ); + let mut arms = do variants.mapi |v_idx, variant| { let body = match variant.node.kind { ast::tuple_variant_kind(ref args) => { @@ -1152,13 +1164,13 @@ fn mk_enum_deser_body( ) ); - // ast for `__d.read_enum_variant($(expr_lambda))` + // ast for `__d.read_enum_variant($expr_arm_names, $(expr_lambda))` let expr_lambda = ext_cx.lambda_expr( ext_cx.expr_method_call( span, ext_cx.expr_var(span, ~"__d"), ext_cx.ident_of(~"read_enum_variant"), - ~[expr_lambda] + ~[expr_arm_names, expr_lambda] ) ); @@ -1174,9 +1186,9 @@ fn mk_enum_deser_body( ) } - #[cfg(test)] mod test { + use core::option::{None, Some}; use std::serialize::Encodable; use std::serialize::Encoder; @@ -1190,6 +1202,9 @@ mod test { CallToEmitNil, CallToEmitStruct(~str,uint), CallToEmitField(~str,uint), + CallToEmitOption, + CallToEmitOptionNone, + CallToEmitOptionSome, // all of the ones I was too lazy to handle: CallToOther } @@ -1281,6 +1296,18 @@ mod test { fn emit_tup_elt(&self, +_idx: uint, f: &fn()) { self.add_unknown_to_log(); f(); } + + fn emit_option(&self, f: &fn()) { + self.add_to_log(CallToEmitOption); + f(); + } + fn emit_option_none(&self) { + self.add_to_log(CallToEmitOptionNone); + } + fn emit_option_some(&self, f: &fn()) { + self.add_to_log(CallToEmitOptionSome); + f(); + } } @@ -1296,13 +1323,58 @@ mod test { Magazine(~str) } - #[test] fn encode_enum_test () { - assert_eq!(to_call_log(Book(34,44)), - ~[CallToEmitEnum (~"Written"), - CallToEmitEnumVariant (~"Book",0,2), - CallToEmitEnumVariantArg (0), - CallToEmitUint (34), - CallToEmitEnumVariantArg (1), - CallToEmitUint (44)]); - } + #[test] + fn test_encode_enum() { + assert_eq!( + to_call_log(Book(34,44)), + ~[ + CallToEmitEnum(~"Written"), + CallToEmitEnumVariant(~"Book",0,2), + CallToEmitEnumVariantArg(0), + CallToEmitUint(34), + CallToEmitEnumVariantArg(1), + CallToEmitUint(44), + ] + ); + } + + pub struct BPos(uint); + + #[auto_encode] + pub struct HasPos { pos : BPos } + + #[test] + fn test_encode_newtype() { + assert_eq!( + to_call_log(HasPos { pos:BPos(48) }), + ~[ + CallToEmitStruct(~"HasPos",1), + CallToEmitField(~"pos",0), + CallToEmitUint(48), + ] + ); + } + + #[test] + fn test_encode_option() { + let mut v = None; + + assert_eq!( + to_call_log(v), + ~[ + CallToEmitOption, + CallToEmitOptionNone, + ] + ); + + v = Some(54u); + assert_eq!( + to_call_log(v), + ~[ + CallToEmitOption, + CallToEmitOptionSome, + CallToEmitUint(54) + ] + ); + } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index ad71441e046..9499f95f0e7 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -152,11 +152,6 @@ pub fn mk_slice_vec_e(cx: @ext_ctxt, sp: span, +exprs: ~[@ast::expr]) mk_vstore_e(cx, sp, mk_base_vec_e(cx, sp, exprs), ast::expr_vstore_slice) } -pub fn mk_fixed_vec_e(cx: @ext_ctxt, sp: span, +exprs: ~[@ast::expr]) - -> @ast::expr { - mk_vstore_e(cx, sp, mk_base_vec_e(cx, sp, exprs), - ast::expr_vstore_fixed(None)) -} pub fn mk_base_str(cx: @ext_ctxt, sp: span, +s: ~str) -> @ast::expr { let lit = ast::lit_str(@s); return mk_lit(cx, sp, lit); diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 6044c3ad3d2..a6f078d07b4 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -42,8 +42,7 @@ pub mod rt { pub use ast::*; pub use parse::token::*; pub use parse::new_parser_from_tts; - pub use codemap::BytePos; - pub use codemap::span; + pub use codemap::{BytePos, span, dummy_spanned}; use print::pprust; use print::pprust::{item_to_str, ty_to_str}; @@ -89,7 +88,7 @@ pub mod rt { } } - impl ToSource for ~[@ast::item] { + impl<'self> ToSource for &'self [@ast::item] { fn to_source(&self, cx: @ext_ctxt) -> ~str { str::connect(self.map(|i| i.to_source(cx)), ~"\n\n") } @@ -101,7 +100,7 @@ pub mod rt { } } - impl ToSource for ~[@ast::Ty] { + impl<'self> ToSource for &'self [@ast::Ty] { fn to_source(&self, cx: @ext_ctxt) -> ~str { str::connect(self.map(|i| i.to_source(cx)), ~", ") } @@ -119,6 +118,90 @@ pub mod rt { } } + impl ToSource for ast::blk { + fn to_source(&self, cx: @ext_ctxt) -> ~str { + pprust::block_to_str(self, cx.parse_sess().interner) + } + } + + impl<'self> ToSource for &'self str { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_str(@str::from_slice(*self))); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for int { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i)); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for i8 { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i8)); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for i16 { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i16)); + pprust::lit_to_str(@lit) + } + } + + + impl ToSource for i32 { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i32)); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for i64 { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i64)); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for uint { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u)); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for u8 { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u8)); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for u16 { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u16)); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for u32 { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u32)); + pprust::lit_to_str(@lit) + } + } + + impl ToSource for u64 { + fn to_source(&self, _cx: @ext_ctxt) -> ~str { + let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u64)); + pprust::lit_to_str(@lit) + } + } + // Alas ... we write these out instead. All redundant. impl ToTokens for ast::ident { @@ -133,7 +216,7 @@ pub mod rt { } } - impl ToTokens for ~[@ast::item] { + impl<'self> ToTokens for &'self [@ast::item] { fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { cx.parse_tts(self.to_source(cx)) } @@ -145,7 +228,7 @@ pub mod rt { } } - impl ToTokens for ~[@ast::Ty] { + impl<'self> ToTokens for &'self [@ast::Ty] { fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { cx.parse_tts(self.to_source(cx)) } @@ -163,6 +246,78 @@ pub mod rt { } } + impl ToTokens for ast::blk { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl<'self> ToTokens for &'self str { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for int { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for i8 { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for i16 { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for i32 { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for i64 { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for uint { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for u8 { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for u16 { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for u32 { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + + impl ToTokens for u64 { + fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] { + cx.parse_tts(self.to_source(cx)) + } + } + pub trait ExtParseUtils { fn parse_item(&self, s: ~str) -> @ast::item; fn parse_expr(&self, s: ~str) -> @ast::expr; |
