diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 3df5a70a0c1..79e491e309b 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -1,21 +1,35 @@ #[forbid(deprecated_mode)]; +use serialization; + // Simple Extensible Binary Markup Language (ebml) reader and writer on a // cursor model. See the specification here: // http://www.matroska.org/technical/specs/rfc/index.html -use core::Option; -use option::{Some, None}; -type EbmlTag = {id: uint, size: uint}; +struct EbmlTag { + id: uint, + size: uint, +} -type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: uint}; +struct EbmlState { + ebml_tag: EbmlTag, + tag_pos: uint, + data_pos: uint, +} // FIXME (#2739): When we have module renaming, make "reader" and "writer" // separate modules within this file. // ebml reading -pub type Doc = {data: @~[u8], start: uint, end: uint}; +struct Doc { + data: @~[u8], + start: uint, + end: uint, +} -type TaggedDoc = {tag: uint, doc: Doc}; +struct TaggedDoc { + tag: uint, + doc: Doc, +} impl Doc: ops::Index { pure fn index(tag: uint) -> Doc { @@ -49,15 +63,17 @@ fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} { } pub fn Doc(data: @~[u8]) -> Doc { - return {data: data, start: 0u, end: vec::len::(*data)}; + Doc { data: data, start: 0u, end: vec::len::(*data) } } pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc { let elt_tag = vuint_at(*data, start); let elt_size = vuint_at(*data, elt_tag.next); let end = elt_size.next + elt_size.val; - return {tag: elt_tag.val, - doc: {data: data, start: elt_size.next, end: end}}; + TaggedDoc { + tag: elt_tag.val, + doc: Doc { data: data, start: elt_size.next, end: end } + } } pub fn maybe_get_doc(d: Doc, tg: uint) -> Option { @@ -67,19 +83,15 @@ pub fn maybe_get_doc(d: Doc, tg: uint) -> Option { let elt_size = vuint_at(*d.data, elt_tag.next); pos = elt_size.next + elt_size.val; if elt_tag.val == tg { - return Some::({ - data: d.data, - start: elt_size.next, - end: pos - }); + return Some(Doc { data: d.data, start: elt_size.next, end: pos }); } } - return None::; + None } pub fn get_doc(d: Doc, tg: uint) -> Doc { match maybe_get_doc(d, tg) { - Some(d) => return d, + Some(d) => d, None => { error!("failed to find block with tag %u", tg); fail; @@ -93,7 +105,8 @@ pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) { let elt_tag = vuint_at(*d.data, pos); let elt_size = vuint_at(*d.data, elt_tag.next); pos = elt_size.next + elt_size.val; - if !it(elt_tag.val, {data: d.data, start: elt_size.next, end: pos}) { + let doc = Doc { data: d.data, start: elt_size.next, end: pos }; + if !it(elt_tag.val, doc) { break; } } @@ -106,7 +119,8 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { let elt_size = vuint_at(*d.data, elt_tag.next); pos = elt_size.next + elt_size.val; if elt_tag.val == tg { - if !it({data: d.data, start: elt_size.next, end: pos}) { + let doc = Doc { data: d.data, start: elt_size.next, end: pos }; + if !it(doc) { break; } } @@ -116,29 +130,29 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::(*d.data, d.start, d.end) } pub fn with_doc_data(d: Doc, f: fn(x: &[u8]) -> T) -> T { - return f(vec::view(*d.data, d.start, d.end)); + f(vec::view(*d.data, d.start, d.end)) } -pub fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); } +pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) } pub fn doc_as_u8(d: Doc) -> u8 { assert d.end == d.start + 1u; - return (*d.data)[d.start]; + (*d.data)[d.start] } pub fn doc_as_u16(d: Doc) -> u16 { assert d.end == d.start + 2u; - return io::u64_from_be_bytes(*d.data, d.start, 2u) as u16; + io::u64_from_be_bytes(*d.data, d.start, 2u) as u16 } pub fn doc_as_u32(d: Doc) -> u32 { assert d.end == d.start + 4u; - return io::u64_from_be_bytes(*d.data, d.start, 4u) as u32; + io::u64_from_be_bytes(*d.data, d.start, 4u) as u32 } pub fn doc_as_u64(d: Doc) -> u64 { assert d.end == d.start + 8u; - return io::u64_from_be_bytes(*d.data, d.start, 8u); + io::u64_from_be_bytes(*d.data, d.start, 8u) } pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } @@ -147,10 +161,9 @@ pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } // ebml writing -type Writer_ = {writer: io::Writer, mut size_positions: ~[uint]}; - -pub enum Writer { - Writer_(Writer_) +struct Serializer { + writer: io::Writer, + priv mut size_positions: ~[uint], } fn write_sized_vuint(w: io::Writer, n: uint, size: uint) { @@ -173,13 +186,13 @@ fn write_vuint(w: io::Writer, n: uint) { fail fmt!("vint to write too big: %?", n); } -pub fn Writer(w: io::Writer) -> Writer { +pub fn Serializer(w: io::Writer) -> Serializer { let size_positions: ~[uint] = ~[]; - return Writer_({writer: w, mut size_positions: size_positions}); + Serializer { writer: w, mut size_positions: size_positions } } // FIXME (#2741): Provide a function to write the standard ebml header. -impl Writer { +impl Serializer { fn start_tag(tag_id: uint) { debug!("Start tag %u", tag_id); @@ -295,12 +308,7 @@ enum EbmlSerializerTag { EsLabel // Used only when debugging } -trait SerializerPriv { - fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint); - fn _emit_label(label: &str); -} - -impl ebml::Writer: SerializerPriv { +priv impl Serializer { // used internally to emit things like the vector length and so on fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) { assert v <= 0xFFFF_FFFF_u; @@ -318,89 +326,123 @@ impl ebml::Writer: SerializerPriv { } } -impl ebml::Writer { - fn emit_opaque(f: fn()) { +impl Serializer { + fn emit_opaque(&self, f: fn()) { do self.wr_tag(EsOpaque as uint) { f() } } } -impl ebml::Writer: serialization::Serializer { - fn emit_nil() {} +impl Serializer: serialization::Serializer { + fn emit_nil(&self) {} - fn emit_uint(v: uint) { self.wr_tagged_u64(EsUint as uint, v as u64); } - fn emit_u64(v: u64) { self.wr_tagged_u64(EsU64 as uint, v); } - fn emit_u32(v: u32) { self.wr_tagged_u32(EsU32 as uint, v); } - fn emit_u16(v: u16) { self.wr_tagged_u16(EsU16 as uint, v); } - fn emit_u8(v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); } + fn emit_uint(&self, v: uint) { + self.wr_tagged_u64(EsUint as uint, v as u64); + } + fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); } + fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); } + fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); } + fn emit_u8(&self, v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); } - fn emit_int(v: int) { self.wr_tagged_i64(EsInt as uint, v as i64); } - fn emit_i64(v: i64) { self.wr_tagged_i64(EsI64 as uint, v); } - fn emit_i32(v: i32) { self.wr_tagged_i32(EsI32 as uint, v); } - fn emit_i16(v: i16) { self.wr_tagged_i16(EsI16 as uint, v); } - fn emit_i8(v: i8) { self.wr_tagged_i8 (EsI8 as uint, v); } + fn emit_int(&self, v: int) { + self.wr_tagged_i64(EsInt as uint, v as i64); + } + fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); } + fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); } + fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); } + fn emit_i8(&self, v: i8) { self.wr_tagged_i8 (EsI8 as uint, v); } - fn emit_bool(v: bool) { self.wr_tagged_u8(EsBool as uint, v as u8) } + fn emit_bool(&self, v: bool) { + self.wr_tagged_u8(EsBool as uint, v as u8) + } // FIXME (#2742): implement these - fn emit_f64(_v: f64) { fail ~"Unimplemented: serializing an f64"; } - fn emit_f32(_v: f32) { fail ~"Unimplemented: serializing an f32"; } - fn emit_float(_v: float) { fail ~"Unimplemented: serializing a float"; } + fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; } + fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; } + fn emit_float(&self, _v: float) { + fail ~"Unimplemented: serializing a float"; + } - fn emit_str(v: &str) { self.wr_tagged_str(EsStr as uint, v) } + fn emit_char(&self, _v: char) { + fail ~"Unimplemented: serializing a char"; + } - fn emit_enum(name: &str, f: fn()) { + fn emit_borrowed_str(&self, v: &str) { + self.wr_tagged_str(EsStr as uint, v) + } + + fn emit_owned_str(&self, v: &str) { + self.emit_borrowed_str(v) + } + + fn emit_managed_str(&self, v: &str) { + self.emit_borrowed_str(v) + } + + fn emit_borrowed(&self, f: fn()) { f() } + fn emit_owned(&self, f: fn()) { f() } + fn emit_managed(&self, f: fn()) { f() } + + fn emit_enum(&self, name: &str, f: fn()) { self._emit_label(name); self.wr_tag(EsEnum as uint, f) } - fn emit_enum_variant(_v_name: &str, v_id: uint, _cnt: uint, f: fn()) { + fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint, + f: fn()) { self._emit_tagged_uint(EsEnumVid, v_id); self.wr_tag(EsEnumBody as uint, f) } - fn emit_enum_variant_arg(_idx: uint, f: fn()) { f() } + fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() } - fn emit_vec(len: uint, f: fn()) { + fn emit_borrowed_vec(&self, len: uint, f: fn()) { do self.wr_tag(EsVec as uint) { self._emit_tagged_uint(EsVecLen, len); f() } } - fn emit_vec_elt(_idx: uint, f: fn()) { + fn emit_owned_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + + fn emit_managed_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + + fn emit_vec_elt(&self, _idx: uint, f: fn()) { self.wr_tag(EsVecElt as uint, f) } - fn emit_box(f: fn()) { f() } - fn emit_uniq(f: fn()) { f() } - fn emit_rec(f: fn()) { f() } - fn emit_rec_field(f_name: &str, _f_idx: uint, f: fn()) { - self._emit_label(f_name); + fn emit_rec(&self, f: fn()) { f() } + fn emit_struct(&self, _name: &str, f: fn()) { f() } + fn emit_field(&self, name: &str, _idx: uint, f: fn()) { + self._emit_label(name); f() } - fn emit_tup(_sz: uint, f: fn()) { f() } - fn emit_tup_elt(_idx: uint, f: fn()) { f() } + + fn emit_tup(&self, _len: uint, f: fn()) { f() } + fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() } } -type EbmlDeserializer_ = {mut parent: ebml::Doc, - mut pos: uint}; - -pub enum EbmlDeserializer { - EbmlDeserializer_(EbmlDeserializer_) +struct Deserializer { + priv mut parent: Doc, + priv mut pos: uint, } -pub fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer { - EbmlDeserializer_({mut parent: d, mut pos: d.start}) +pub fn Deserializer(d: Doc) -> Deserializer { + Deserializer { mut parent: d, mut pos: d.start } } -priv impl EbmlDeserializer { +priv impl Deserializer { fn _check_label(lbl: &str) { if self.pos < self.parent.end { - let {tag: r_tag, doc: r_doc} = - ebml::doc_at(self.parent.data, self.pos); + let TaggedDoc { tag: r_tag, doc: r_doc } = + doc_at(self.parent.data, self.pos); + if r_tag == (EsLabel as uint) { self.pos = r_doc.end; - let str = ebml::doc_as_str(r_doc); + let str = doc_as_str(r_doc); if lbl != str { fail fmt!("Expected label %s but found %s", lbl, str); } @@ -408,13 +450,13 @@ priv impl EbmlDeserializer { } } - fn next_doc(exp_tag: EbmlSerializerTag) -> ebml::Doc { + fn next_doc(exp_tag: EbmlSerializerTag) -> Doc { debug!(". next_doc(exp_tag=%?)", exp_tag); if self.pos >= self.parent.end { fail ~"no more documents in current node!"; } - let {tag: r_tag, doc: r_doc} = - ebml::doc_at(self.parent.data, self.pos); + let TaggedDoc { tag: r_tag, doc: r_doc } = + doc_at(self.parent.data, self.pos); debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?", copy self.parent.start, copy self.parent.end, copy self.pos, r_tag, r_doc.start, r_doc.end); @@ -427,10 +469,10 @@ priv impl EbmlDeserializer { r_doc.end, self.parent.end); } self.pos = r_doc.end; - return r_doc; + r_doc } - fn push_doc(d: ebml::Doc, f: fn() -> T) -> T{ + fn push_doc(d: Doc, f: fn() -> T) -> T{ let old_parent = self.parent; let old_pos = self.pos; self.parent = d; @@ -442,63 +484,76 @@ priv impl EbmlDeserializer { } fn _next_uint(exp_tag: EbmlSerializerTag) -> uint { - let r = ebml::doc_as_u32(self.next_doc(exp_tag)); + let r = doc_as_u32(self.next_doc(exp_tag)); debug!("_next_uint exp_tag=%? result=%?", exp_tag, r); - return r as uint; + r as uint } } -impl EbmlDeserializer { - fn read_opaque(op: fn(ebml::Doc) -> R) -> R { +impl Deserializer { + fn read_opaque(&self, op: fn(Doc) -> R) -> R { do self.push_doc(self.next_doc(EsOpaque)) { op(copy self.parent) } } } -impl EbmlDeserializer: serialization::Deserializer { - fn read_nil() -> () { () } +impl Deserializer: serialization::Deserializer { + fn read_nil(&self) -> () { () } - fn read_u64() -> u64 { ebml::doc_as_u64(self.next_doc(EsU64)) } - fn read_u32() -> u32 { ebml::doc_as_u32(self.next_doc(EsU32)) } - fn read_u16() -> u16 { ebml::doc_as_u16(self.next_doc(EsU16)) } - fn read_u8 () -> u8 { ebml::doc_as_u8 (self.next_doc(EsU8 )) } - fn read_uint() -> uint { - let v = ebml::doc_as_u64(self.next_doc(EsUint)); + fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) } + fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) } + fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) } + fn read_u8 (&self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) } + fn read_uint(&self) -> uint { + let v = doc_as_u64(self.next_doc(EsUint)); if v > (core::uint::max_value as u64) { fail fmt!("uint %? too large for this architecture", v); } - return v as uint; + v as uint } - fn read_i64() -> i64 { ebml::doc_as_u64(self.next_doc(EsI64)) as i64 } - fn read_i32() -> i32 { ebml::doc_as_u32(self.next_doc(EsI32)) as i32 } - fn read_i16() -> i16 { ebml::doc_as_u16(self.next_doc(EsI16)) as i16 } - fn read_i8 () -> i8 { ebml::doc_as_u8 (self.next_doc(EsI8 )) as i8 } - fn read_int() -> int { - let v = ebml::doc_as_u64(self.next_doc(EsInt)) as i64; + fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 } + fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 } + fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 } + fn read_i8 (&self) -> i8 { doc_as_u8 (self.next_doc(EsI8 )) as i8 } + fn read_int(&self) -> int { + let v = doc_as_u64(self.next_doc(EsInt)) as i64; if v > (int::max_value as i64) || v < (int::min_value as i64) { fail fmt!("int %? out of range for this architecture", v); } - return v as int; + v as int } - fn read_bool() -> bool { ebml::doc_as_u8(self.next_doc(EsBool)) as bool } + fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool } - fn read_f64() -> f64 { fail ~"read_f64()"; } - fn read_f32() -> f32 { fail ~"read_f32()"; } - fn read_float() -> float { fail ~"read_float()"; } + fn read_f64(&self) -> f64 { fail ~"read_f64()"; } + fn read_f32(&self) -> f32 { fail ~"read_f32()"; } + fn read_float(&self) -> float { fail ~"read_float()"; } - fn read_str() -> ~str { ebml::doc_as_str(self.next_doc(EsStr)) } + fn read_char(&self) -> char { fail ~"read_char()"; } + + fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) } + fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; } // Compound types: - fn read_enum(name: &str, f: fn() -> T) -> T { + fn read_owned(&self, f: fn() -> T) -> T { + debug!("read_owned()"); + f() + } + + fn read_managed(&self, f: fn() -> T) -> T { + debug!("read_managed()"); + f() + } + + fn read_enum(&self, name: &str, f: fn() -> T) -> T { debug!("read_enum(%s)", name); self._check_label(name); self.push_doc(self.next_doc(EsEnum), f) } - fn read_enum_variant(f: fn(uint) -> T) -> T { + fn read_enum_variant(&self, f: fn(uint) -> T) -> T { debug!("read_enum_variant()"); let idx = self._next_uint(EsEnumVid); debug!(" idx=%u", idx); @@ -507,13 +562,13 @@ impl EbmlDeserializer: serialization::Deserializer { } } - fn read_enum_variant_arg(idx: uint, f: fn() -> T) -> T { + fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T { debug!("read_enum_variant_arg(idx=%u)", idx); f() } - fn read_vec(f: fn(uint) -> T) -> T { - debug!("read_vec()"); + fn read_owned_vec(&self, f: fn(uint) -> T) -> T { + debug!("read_owned_vec()"); do self.push_doc(self.next_doc(EsVec)) { let len = self._next_uint(EsVecLen); debug!(" len=%u", len); @@ -521,104 +576,69 @@ impl EbmlDeserializer: serialization::Deserializer { } } - fn read_vec_elt(idx: uint, f: fn() -> T) -> T { + fn read_managed_vec(&self, f: fn(uint) -> T) -> T { + debug!("read_managed_vec()"); + do self.push_doc(self.next_doc(EsVec)) { + let len = self._next_uint(EsVecLen); + debug!(" len=%u", len); + f(len) + } + } + + fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { debug!("read_vec_elt(idx=%u)", idx); self.push_doc(self.next_doc(EsVecElt), f) } - fn read_box(f: fn() -> T) -> T { - debug!("read_box()"); - f() - } - - fn read_uniq(f: fn() -> T) -> T { - debug!("read_uniq()"); - f() - } - - fn read_rec(f: fn() -> T) -> T { + fn read_rec(&self, f: fn() -> T) -> T { debug!("read_rec()"); f() } - fn read_rec_field(f_name: &str, f_idx: uint, f: fn() -> T) -> T { - debug!("read_rec_field(%s, idx=%u)", f_name, f_idx); - self._check_label(f_name); + fn read_struct(&self, name: &str, f: fn() -> T) -> T { + debug!("read_struct(name=%s)", name); f() } - fn read_tup(sz: uint, f: fn() -> T) -> T { - debug!("read_tup(sz=%u)", sz); + fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { + debug!("read_field(name=%s, idx=%u)", name, idx); + self._check_label(name); f() } - fn read_tup_elt(idx: uint, f: fn() -> T) -> T { + fn read_tup(&self, len: uint, f: fn() -> T) -> T { + debug!("read_tup(len=%u)", len); + f() + } + + fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { debug!("read_tup_elt(idx=%u)", idx); f() } } - // ___________________________________________________________________________ // Testing -#[test] -fn test_option_int() { - fn serialize_1(s: &S, v: int) { - s.emit_i64(v as i64); - } - - fn serialize_0(s: &S, v: Option) { - do s.emit_enum(~"core::option::t") { - match v { - None => s.emit_enum_variant( - ~"core::option::None", 0u, 0u, || { } ), - Some(v0) => { - do s.emit_enum_variant(~"core::option::some", 1u, 1u) { - s.emit_enum_variant_arg(0u, || serialize_1(s, v0)); - } - } - } +#[cfg(test)] +mod tests { + #[test] + fn test_option_int() { + fn test_v(v: Option) { + debug!("v == %?", v); + let bytes = do io::with_bytes_writer |wr| { + let ebml_w = Serializer(wr); + v.serialize(&ebml_w) + }; + let ebml_doc = Doc(@bytes); + let deser = Deserializer(ebml_doc); + let v1 = serialization::deserialize(&deser); + debug!("v1 == %?", v1); + assert v == v1; } - } - fn deserialize_1(s: &S) -> int { - s.read_i64() as int + test_v(Some(22)); + test_v(None); + test_v(Some(3)); } - - fn deserialize_0(s: &S) -> Option { - do s.read_enum(~"core::option::t") { - do s.read_enum_variant |i| { - match i { - 0 => None, - 1 => { - let v0 = do s.read_enum_variant_arg(0u) { - deserialize_1(s) - }; - Some(v0) - } - _ => { - fail #fmt("deserialize_0: unexpected variant %u", i); - } - } - } - } - } - - fn test_v(v: Option) { - debug!("v == %?", v); - let bytes = do io::with_bytes_writer |wr| { - let ebml_w = ebml::Writer(wr); - serialize_0(&ebml_w, v); - }; - let ebml_doc = ebml::Doc(@bytes); - let deser = ebml_deserializer(ebml_doc); - let v1 = deserialize_0(&deser); - debug!("v1 == %?", v1); - assert v == v1; - } - - test_v(Some(22)); - test_v(None); - test_v(Some(3)); } diff --git a/src/libstd/ebml2.rs b/src/libstd/ebml2.rs index f88aad1ac63..f5410233c92 100644 --- a/src/libstd/ebml2.rs +++ b/src/libstd/ebml2.rs @@ -1,644 +1 @@ -#[forbid(deprecated_mode)]; -use serialization2; - -// Simple Extensible Binary Markup Language (ebml) reader and writer on a -// cursor model. See the specification here: -// http://www.matroska.org/technical/specs/rfc/index.html - -struct EbmlTag { - id: uint, - size: uint, -} - -struct EbmlState { - ebml_tag: EbmlTag, - tag_pos: uint, - data_pos: uint, -} - -// FIXME (#2739): When we have module renaming, make "reader" and "writer" -// separate modules within this file. - -// ebml reading -struct Doc { - data: @~[u8], - start: uint, - end: uint, -} - -struct TaggedDoc { - tag: uint, - doc: Doc, -} - -impl Doc: ops::Index { - pure fn index(tag: uint) -> Doc { - unsafe { - get_doc(self, tag) - } - } -} - -fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} { - let a = data[start]; - if a & 0x80u8 != 0u8 { - return {val: (a & 0x7fu8) as uint, next: start + 1u}; - } - if a & 0x40u8 != 0u8 { - return {val: ((a & 0x3fu8) as uint) << 8u | - (data[start + 1u] as uint), - next: start + 2u}; - } else if a & 0x20u8 != 0u8 { - return {val: ((a & 0x1fu8) as uint) << 16u | - (data[start + 1u] as uint) << 8u | - (data[start + 2u] as uint), - next: start + 3u}; - } else if a & 0x10u8 != 0u8 { - return {val: ((a & 0x0fu8) as uint) << 24u | - (data[start + 1u] as uint) << 16u | - (data[start + 2u] as uint) << 8u | - (data[start + 3u] as uint), - next: start + 4u}; - } else { error!("vint too big"); fail; } -} - -pub fn Doc(data: @~[u8]) -> Doc { - Doc { data: data, start: 0u, end: vec::len::(*data) } -} - -pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc { - let elt_tag = vuint_at(*data, start); - let elt_size = vuint_at(*data, elt_tag.next); - let end = elt_size.next + elt_size.val; - TaggedDoc { - tag: elt_tag.val, - doc: Doc { data: data, start: elt_size.next, end: end } - } -} - -pub fn maybe_get_doc(d: Doc, tg: uint) -> Option { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(*d.data, pos); - let elt_size = vuint_at(*d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - return Some(Doc { data: d.data, start: elt_size.next, end: pos }); - } - } - None -} - -pub fn get_doc(d: Doc, tg: uint) -> Doc { - match maybe_get_doc(d, tg) { - Some(d) => d, - None => { - error!("failed to find block with tag %u", tg); - fail; - } - } -} - -pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(*d.data, pos); - let elt_size = vuint_at(*d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - let doc = Doc { data: d.data, start: elt_size.next, end: pos }; - if !it(elt_tag.val, doc) { - break; - } - } -} - -pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(*d.data, pos); - let elt_size = vuint_at(*d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - let doc = Doc { data: d.data, start: elt_size.next, end: pos }; - if !it(doc) { - break; - } - } - } -} - -pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::(*d.data, d.start, d.end) } - -pub fn with_doc_data(d: Doc, f: fn(x: &[u8]) -> T) -> T { - f(vec::view(*d.data, d.start, d.end)) -} - -pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) } - -pub fn doc_as_u8(d: Doc) -> u8 { - assert d.end == d.start + 1u; - (*d.data)[d.start] -} - -pub fn doc_as_u16(d: Doc) -> u16 { - assert d.end == d.start + 2u; - io::u64_from_be_bytes(*d.data, d.start, 2u) as u16 -} - -pub fn doc_as_u32(d: Doc) -> u32 { - assert d.end == d.start + 4u; - io::u64_from_be_bytes(*d.data, d.start, 4u) as u32 -} - -pub fn doc_as_u64(d: Doc) -> u64 { - assert d.end == d.start + 8u; - io::u64_from_be_bytes(*d.data, d.start, 8u) -} - -pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } -pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } -pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } -pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } - -// ebml writing -struct Serializer { - writer: io::Writer, - priv mut size_positions: ~[uint], -} - -fn write_sized_vuint(w: io::Writer, n: uint, size: uint) { - match size { - 1u => w.write(&[0x80u8 | (n as u8)]), - 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]), - 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8, - n as u8]), - 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8, - (n >> 8_u) as u8, n as u8]), - _ => fail fmt!("vint to write too big: %?", n) - }; -} - -fn write_vuint(w: io::Writer, n: uint) { - if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; } - if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; } - if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; } - if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; } - fail fmt!("vint to write too big: %?", n); -} - -pub fn Serializer(w: io::Writer) -> Serializer { - let size_positions: ~[uint] = ~[]; - Serializer { writer: w, mut size_positions: size_positions } -} - -// FIXME (#2741): Provide a function to write the standard ebml header. -impl Serializer { - fn start_tag(tag_id: uint) { - debug!("Start tag %u", tag_id); - - // Write the enum ID: - write_vuint(self.writer, tag_id); - - // Write a placeholder four-byte size. - self.size_positions.push(self.writer.tell()); - let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8]; - self.writer.write(zeroes); - } - - fn end_tag() { - let last_size_pos = self.size_positions.pop(); - let cur_pos = self.writer.tell(); - self.writer.seek(last_size_pos as int, io::SeekSet); - let size = (cur_pos - last_size_pos - 4u); - write_sized_vuint(self.writer, size, 4u); - self.writer.seek(cur_pos as int, io::SeekSet); - - debug!("End tag (size = %u)", size); - } - - fn wr_tag(tag_id: uint, blk: fn()) { - self.start_tag(tag_id); - blk(); - self.end_tag(); - } - - fn wr_tagged_bytes(tag_id: uint, b: &[u8]) { - write_vuint(self.writer, tag_id); - write_vuint(self.writer, vec::len(b)); - self.writer.write(b); - } - - fn wr_tagged_u64(tag_id: uint, v: u64) { - do io::u64_to_be_bytes(v, 8u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_u32(tag_id: uint, v: u32) { - do io::u64_to_be_bytes(v as u64, 4u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_u16(tag_id: uint, v: u16) { - do io::u64_to_be_bytes(v as u64, 2u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_u8(tag_id: uint, v: u8) { - self.wr_tagged_bytes(tag_id, &[v]); - } - - fn wr_tagged_i64(tag_id: uint, v: i64) { - do io::u64_to_be_bytes(v as u64, 8u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_i32(tag_id: uint, v: i32) { - do io::u64_to_be_bytes(v as u64, 4u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_i16(tag_id: uint, v: i16) { - do io::u64_to_be_bytes(v as u64, 2u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_i8(tag_id: uint, v: i8) { - self.wr_tagged_bytes(tag_id, &[v as u8]); - } - - fn wr_tagged_str(tag_id: uint, v: &str) { - str::byte_slice(v, |b| self.wr_tagged_bytes(tag_id, b)); - } - - fn wr_bytes(b: &[u8]) { - debug!("Write %u bytes", vec::len(b)); - self.writer.write(b); - } - - fn wr_str(s: &str) { - debug!("Write str: %?", s); - self.writer.write(str::to_bytes(s)); - } -} - -// FIXME (#2743): optionally perform "relaxations" on end_tag to more -// efficiently encode sizes; this is a fixed point iteration - -// Set to true to generate more debugging in EBML serialization. -// Totally lame approach. -const debug: bool = false; - -enum EbmlSerializerTag { - EsUint, EsU64, EsU32, EsU16, EsU8, - EsInt, EsI64, EsI32, EsI16, EsI8, - EsBool, - EsStr, - EsF64, EsF32, EsFloat, - EsEnum, EsEnumVid, EsEnumBody, - EsVec, EsVecLen, EsVecElt, - - EsOpaque, - - EsLabel // Used only when debugging -} - -priv impl Serializer { - // used internally to emit things like the vector length and so on - fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) { - assert v <= 0xFFFF_FFFF_u; - self.wr_tagged_u32(t as uint, v as u32); - } - - fn _emit_label(label: &str) { - // There are various strings that we have access to, such as - // the name of a record field, which do not actually appear in - // the serialized EBML (normally). This is just for - // efficiency. When debugging, though, we can emit such - // labels and then they will be checked by deserializer to - // try and check failures more quickly. - if debug { self.wr_tagged_str(EsLabel as uint, label) } - } -} - -impl Serializer { - fn emit_opaque(&self, f: fn()) { - do self.wr_tag(EsOpaque as uint) { - f() - } - } -} - -impl Serializer: serialization2::Serializer { - fn emit_nil(&self) {} - - fn emit_uint(&self, v: uint) { - self.wr_tagged_u64(EsUint as uint, v as u64); - } - fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); } - fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); } - fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); } - fn emit_u8(&self, v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); } - - fn emit_int(&self, v: int) { - self.wr_tagged_i64(EsInt as uint, v as i64); - } - fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); } - fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); } - fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); } - fn emit_i8(&self, v: i8) { self.wr_tagged_i8 (EsI8 as uint, v); } - - fn emit_bool(&self, v: bool) { - self.wr_tagged_u8(EsBool as uint, v as u8) - } - - // FIXME (#2742): implement these - fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; } - fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; } - fn emit_float(&self, _v: float) { - fail ~"Unimplemented: serializing a float"; - } - - fn emit_char(&self, _v: char) { - fail ~"Unimplemented: serializing a char"; - } - - fn emit_borrowed_str(&self, v: &str) { - self.wr_tagged_str(EsStr as uint, v) - } - - fn emit_owned_str(&self, v: &str) { - self.emit_borrowed_str(v) - } - - fn emit_managed_str(&self, v: &str) { - self.emit_borrowed_str(v) - } - - fn emit_borrowed(&self, f: fn()) { f() } - fn emit_owned(&self, f: fn()) { f() } - fn emit_managed(&self, f: fn()) { f() } - - fn emit_enum(&self, name: &str, f: fn()) { - self._emit_label(name); - self.wr_tag(EsEnum as uint, f) - } - fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint, - f: fn()) { - self._emit_tagged_uint(EsEnumVid, v_id); - self.wr_tag(EsEnumBody as uint, f) - } - fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() } - - fn emit_borrowed_vec(&self, len: uint, f: fn()) { - do self.wr_tag(EsVec as uint) { - self._emit_tagged_uint(EsVecLen, len); - f() - } - } - - fn emit_owned_vec(&self, len: uint, f: fn()) { - self.emit_borrowed_vec(len, f) - } - - fn emit_managed_vec(&self, len: uint, f: fn()) { - self.emit_borrowed_vec(len, f) - } - - fn emit_vec_elt(&self, _idx: uint, f: fn()) { - self.wr_tag(EsVecElt as uint, f) - } - - fn emit_rec(&self, f: fn()) { f() } - fn emit_struct(&self, _name: &str, f: fn()) { f() } - fn emit_field(&self, name: &str, _idx: uint, f: fn()) { - self._emit_label(name); - f() - } - - fn emit_tup(&self, _len: uint, f: fn()) { f() } - fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() } -} - -struct Deserializer { - priv mut parent: Doc, - priv mut pos: uint, -} - -pub fn Deserializer(d: Doc) -> Deserializer { - Deserializer { mut parent: d, mut pos: d.start } -} - -priv impl Deserializer { - fn _check_label(lbl: &str) { - if self.pos < self.parent.end { - let TaggedDoc { tag: r_tag, doc: r_doc } = - doc_at(self.parent.data, self.pos); - - if r_tag == (EsLabel as uint) { - self.pos = r_doc.end; - let str = doc_as_str(r_doc); - if lbl != str { - fail fmt!("Expected label %s but found %s", lbl, str); - } - } - } - } - - fn next_doc(exp_tag: EbmlSerializerTag) -> Doc { - debug!(". next_doc(exp_tag=%?)", exp_tag); - if self.pos >= self.parent.end { - fail ~"no more documents in current node!"; - } - let TaggedDoc { tag: r_tag, doc: r_doc } = - doc_at(self.parent.data, self.pos); - debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?", - copy self.parent.start, copy self.parent.end, - copy self.pos, r_tag, r_doc.start, r_doc.end); - if r_tag != (exp_tag as uint) { - fail fmt!("expected EMBL doc with tag %? but found tag %?", - exp_tag, r_tag); - } - if r_doc.end > self.parent.end { - fail fmt!("invalid EBML, child extends to 0x%x, parent to 0x%x", - r_doc.end, self.parent.end); - } - self.pos = r_doc.end; - r_doc - } - - fn push_doc(d: Doc, f: fn() -> T) -> T{ - let old_parent = self.parent; - let old_pos = self.pos; - self.parent = d; - self.pos = d.start; - let r = f(); - self.parent = old_parent; - self.pos = old_pos; - move r - } - - fn _next_uint(exp_tag: EbmlSerializerTag) -> uint { - let r = doc_as_u32(self.next_doc(exp_tag)); - debug!("_next_uint exp_tag=%? result=%?", exp_tag, r); - r as uint - } -} - -impl Deserializer { - fn read_opaque(&self, op: fn(Doc) -> R) -> R { - do self.push_doc(self.next_doc(EsOpaque)) { - op(copy self.parent) - } - } -} - -impl Deserializer: serialization2::Deserializer { - fn read_nil(&self) -> () { () } - - fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) } - fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) } - fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) } - fn read_u8 (&self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) } - fn read_uint(&self) -> uint { - let v = doc_as_u64(self.next_doc(EsUint)); - if v > (core::uint::max_value as u64) { - fail fmt!("uint %? too large for this architecture", v); - } - v as uint - } - - fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 } - fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 } - fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 } - fn read_i8 (&self) -> i8 { doc_as_u8 (self.next_doc(EsI8 )) as i8 } - fn read_int(&self) -> int { - let v = doc_as_u64(self.next_doc(EsInt)) as i64; - if v > (int::max_value as i64) || v < (int::min_value as i64) { - fail fmt!("int %? out of range for this architecture", v); - } - v as int - } - - fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool } - - fn read_f64(&self) -> f64 { fail ~"read_f64()"; } - fn read_f32(&self) -> f32 { fail ~"read_f32()"; } - fn read_float(&self) -> float { fail ~"read_float()"; } - - fn read_char(&self) -> char { fail ~"read_char()"; } - - fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) } - fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; } - - // Compound types: - fn read_owned(&self, f: fn() -> T) -> T { - debug!("read_owned()"); - f() - } - - fn read_managed(&self, f: fn() -> T) -> T { - debug!("read_managed()"); - f() - } - - fn read_enum(&self, name: &str, f: fn() -> T) -> T { - debug!("read_enum(%s)", name); - self._check_label(name); - self.push_doc(self.next_doc(EsEnum), f) - } - - fn read_enum_variant(&self, f: fn(uint) -> T) -> T { - debug!("read_enum_variant()"); - let idx = self._next_uint(EsEnumVid); - debug!(" idx=%u", idx); - do self.push_doc(self.next_doc(EsEnumBody)) { - f(idx) - } - } - - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T { - debug!("read_enum_variant_arg(idx=%u)", idx); - f() - } - - fn read_owned_vec(&self, f: fn(uint) -> T) -> T { - debug!("read_owned_vec()"); - do self.push_doc(self.next_doc(EsVec)) { - let len = self._next_uint(EsVecLen); - debug!(" len=%u", len); - f(len) - } - } - - fn read_managed_vec(&self, f: fn(uint) -> T) -> T { - debug!("read_managed_vec()"); - do self.push_doc(self.next_doc(EsVec)) { - let len = self._next_uint(EsVecLen); - debug!(" len=%u", len); - f(len) - } - } - - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { - debug!("read_vec_elt(idx=%u)", idx); - self.push_doc(self.next_doc(EsVecElt), f) - } - - fn read_rec(&self, f: fn() -> T) -> T { - debug!("read_rec()"); - f() - } - - fn read_struct(&self, name: &str, f: fn() -> T) -> T { - debug!("read_struct(name=%s)", name); - f() - } - - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { - debug!("read_field(name=%s, idx=%u)", name, idx); - self._check_label(name); - f() - } - - fn read_tup(&self, len: uint, f: fn() -> T) -> T { - debug!("read_tup(len=%u)", len); - f() - } - - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { - debug!("read_tup_elt(idx=%u)", idx); - f() - } -} - -// ___________________________________________________________________________ -// Testing - -#[cfg(test)] -mod tests { - #[test] - fn test_option_int() { - fn test_v(v: Option) { - debug!("v == %?", v); - let bytes = do io::with_bytes_writer |wr| { - let ebml_w = Serializer(wr); - v.serialize(&ebml_w) - }; - let ebml_doc = Doc(@bytes); - let deser = Deserializer(ebml_doc); - let v1 = serialization2::deserialize(&deser); - debug!("v1 == %?", v1); - assert v == v1; - } - - test_v(Some(22)); - test_v(None); - test_v(Some(3)); - } -} +pub use ebml::*; diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 09d00216209..fa7c0286dc1 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -63,7 +63,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer { Serializer { wr: wr } } -pub impl Serializer: serialization2::Serializer { +pub impl Serializer: serialization::Serializer { fn emit_nil(&self) { self.wr.write_str("null") } fn emit_uint(&self, v: uint) { self.emit_float(v as float); } @@ -167,7 +167,7 @@ pub fn PrettySerializer(wr: io::Writer) -> PrettySerializer { PrettySerializer { wr: wr, indent: 0 } } -pub impl PrettySerializer: serialization2::Serializer { +pub impl PrettySerializer: serialization::Serializer { fn emit_nil(&self) { self.wr.write_str("null") } fn emit_uint(&self, v: uint) { self.emit_float(v as float); } @@ -273,8 +273,8 @@ pub impl PrettySerializer: serialization2::Serializer { } } -pub impl Json: serialization2::Serializable { - fn serialize(&self, s: &S) { +pub impl Json: serialization::Serializable { + fn serialize(&self, s: &S) { match *self { Number(v) => v.serialize(s), String(ref v) => v.serialize(s), @@ -721,7 +721,7 @@ priv impl Deserializer { } } -pub impl Deserializer: serialization2::Deserializer { +pub impl Deserializer: serialization::Deserializer { fn read_nil(&self) -> () { debug!("read_nil"); match *self.pop() { diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index bc528800666..6119c03cdca 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -2,131 +2,175 @@ use io::Writer; use io::WriterUtil; -use serialization::Serializer; +use serialization; -impl Writer: Serializer { - fn emit_nil() { - self.write_str(~"()") +pub struct Serializer { + wr: io::Writer, +} + +pub fn Serializer(wr: io::Writer) -> Serializer { + Serializer { wr: wr } +} + +pub impl Serializer: serialization::Serializer { + fn emit_nil(&self) { + self.wr.write_str(~"()") } - fn emit_uint(v: uint) { - self.write_str(fmt!("%?u", v)); + fn emit_uint(&self, v: uint) { + self.wr.write_str(fmt!("%?u", v)); } - fn emit_u64(v: u64) { - self.write_str(fmt!("%?_u64", v)); + fn emit_u64(&self, v: u64) { + self.wr.write_str(fmt!("%?_u64", v)); } - fn emit_u32(v: u32) { - self.write_str(fmt!("%?_u32", v)); + fn emit_u32(&self, v: u32) { + self.wr.write_str(fmt!("%?_u32", v)); } - fn emit_u16(v: u16) { - self.write_str(fmt!("%?_u16", v)); + fn emit_u16(&self, v: u16) { + self.wr.write_str(fmt!("%?_u16", v)); } - fn emit_u8(v: u8) { - self.write_str(fmt!("%?_u8", v)); + fn emit_u8(&self, v: u8) { + self.wr.write_str(fmt!("%?_u8", v)); } - fn emit_int(v: int) { - self.write_str(fmt!("%?", v)); + fn emit_int(&self, v: int) { + self.wr.write_str(fmt!("%?", v)); } - fn emit_i64(v: i64) { - self.write_str(fmt!("%?_i64", v)); + fn emit_i64(&self, v: i64) { + self.wr.write_str(fmt!("%?_i64", v)); } - fn emit_i32(v: i32) { - self.write_str(fmt!("%?_i32", v)); + fn emit_i32(&self, v: i32) { + self.wr.write_str(fmt!("%?_i32", v)); } - fn emit_i16(v: i16) { - self.write_str(fmt!("%?_i16", v)); + fn emit_i16(&self, v: i16) { + self.wr.write_str(fmt!("%?_i16", v)); } - fn emit_i8(v: i8) { - self.write_str(fmt!("%?_i8", v)); + fn emit_i8(&self, v: i8) { + self.wr.write_str(fmt!("%?_i8", v)); } - fn emit_bool(v: bool) { - self.write_str(fmt!("%b", v)); + fn emit_bool(&self, v: bool) { + self.wr.write_str(fmt!("%b", v)); } - fn emit_float(v: float) { - self.write_str(fmt!("%?_f", v)); + fn emit_float(&self, v: float) { + self.wr.write_str(fmt!("%?_f", v)); } - fn emit_f64(v: f64) { - self.write_str(fmt!("%?_f64", v)); + fn emit_f64(&self, v: f64) { + self.wr.write_str(fmt!("%?_f64", v)); } - fn emit_f32(v: f32) { - self.write_str(fmt!("%?_f32", v)); + fn emit_f32(&self, v: f32) { + self.wr.write_str(fmt!("%?_f32", v)); } - fn emit_str(v: &str) { - self.write_str(fmt!("%?", v)); + fn emit_char(&self, v: char) { + self.wr.write_str(fmt!("%?", v)); } - fn emit_enum(_name: &str, f: fn()) { + fn emit_borrowed_str(&self, v: &str) { + self.wr.write_str(fmt!("&%?", v)); + } + + fn emit_owned_str(&self, v: &str) { + self.wr.write_str(fmt!("~%?", v)); + } + + fn emit_managed_str(&self, v: &str) { + self.wr.write_str(fmt!("@%?", v)); + } + + fn emit_borrowed(&self, f: fn()) { + self.wr.write_str(~"&"); f(); } - fn emit_enum_variant(v_name: &str, _v_id: uint, sz: uint, f: fn()) { - self.write_str(v_name); - if sz > 0u { self.write_str(~"("); } - f(); - if sz > 0u { self.write_str(~")"); } - } - - fn emit_enum_variant_arg(idx: uint, f: fn()) { - if idx > 0u { self.write_str(~", "); } + fn emit_owned(&self, f: fn()) { + self.wr.write_str(~"~"); f(); } - fn emit_vec(_len: uint, f: fn()) { - self.write_str(~"["); - f(); - self.write_str(~"]"); - } - - fn emit_vec_elt(idx: uint, f: fn()) { - if idx > 0u { self.write_str(~", "); } + fn emit_managed(&self, f: fn()) { + self.wr.write_str(~"@"); f(); } - fn emit_box(f: fn()) { - self.write_str(~"@"); + fn emit_enum(&self, _name: &str, f: fn()) { f(); } - fn emit_uniq(f: fn()) { - self.write_str(~"~"); + fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint, + f: fn()) { + self.wr.write_str(v_name); + if sz > 0u { self.wr.write_str(~"("); } + f(); + if sz > 0u { self.wr.write_str(~")"); } + } + + fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } f(); } - fn emit_rec(f: fn()) { - self.write_str(~"{"); + fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"&["); f(); - self.write_str(~"}"); + self.wr.write_str(~"]"); } - fn emit_rec_field(f_name: &str, f_idx: uint, f: fn()) { - if f_idx > 0u { self.write_str(~", "); } - self.write_str(f_name); - self.write_str(~": "); + fn emit_owned_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"~["); + f(); + self.wr.write_str(~"]"); + } + + fn emit_managed_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"@["); + f(); + self.wr.write_str(~"]"); + } + + fn emit_vec_elt(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } f(); } - fn emit_tup(_sz: uint, f: fn()) { - self.write_str(~"("); + fn emit_rec(&self, f: fn()) { + self.wr.write_str(~"{"); f(); - self.write_str(~")"); + self.wr.write_str(~"}"); } - fn emit_tup_elt(idx: uint, f: fn()) { - if idx > 0u { self.write_str(~", "); } + fn emit_struct(&self, name: &str, f: fn()) { + self.wr.write_str(fmt!("%s {", name)); + f(); + self.wr.write_str(~"}"); + } + + fn emit_field(&self, name: &str, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } + self.wr.write_str(name); + self.wr.write_str(~": "); + f(); + } + + fn emit_tup(&self, _len: uint, f: fn()) { + self.wr.write_str(~"("); + f(); + self.wr.write_str(~")"); + } + + fn emit_tup_elt(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } f(); } } diff --git a/src/libstd/prettyprint2.rs b/src/libstd/prettyprint2.rs index 87af519eb12..a3bf40ecf72 100644 --- a/src/libstd/prettyprint2.rs +++ b/src/libstd/prettyprint2.rs @@ -1,176 +1 @@ -#[forbid(deprecated_mode)]; - -use io::Writer; -use io::WriterUtil; -use serialization2; - -pub struct Serializer { - wr: io::Writer, -} - -pub fn Serializer(wr: io::Writer) -> Serializer { - Serializer { wr: wr } -} - -pub impl Serializer: serialization2::Serializer { - fn emit_nil(&self) { - self.wr.write_str(~"()") - } - - fn emit_uint(&self, v: uint) { - self.wr.write_str(fmt!("%?u", v)); - } - - fn emit_u64(&self, v: u64) { - self.wr.write_str(fmt!("%?_u64", v)); - } - - fn emit_u32(&self, v: u32) { - self.wr.write_str(fmt!("%?_u32", v)); - } - - fn emit_u16(&self, v: u16) { - self.wr.write_str(fmt!("%?_u16", v)); - } - - fn emit_u8(&self, v: u8) { - self.wr.write_str(fmt!("%?_u8", v)); - } - - fn emit_int(&self, v: int) { - self.wr.write_str(fmt!("%?", v)); - } - - fn emit_i64(&self, v: i64) { - self.wr.write_str(fmt!("%?_i64", v)); - } - - fn emit_i32(&self, v: i32) { - self.wr.write_str(fmt!("%?_i32", v)); - } - - fn emit_i16(&self, v: i16) { - self.wr.write_str(fmt!("%?_i16", v)); - } - - fn emit_i8(&self, v: i8) { - self.wr.write_str(fmt!("%?_i8", v)); - } - - fn emit_bool(&self, v: bool) { - self.wr.write_str(fmt!("%b", v)); - } - - fn emit_float(&self, v: float) { - self.wr.write_str(fmt!("%?_f", v)); - } - - fn emit_f64(&self, v: f64) { - self.wr.write_str(fmt!("%?_f64", v)); - } - - fn emit_f32(&self, v: f32) { - self.wr.write_str(fmt!("%?_f32", v)); - } - - fn emit_char(&self, v: char) { - self.wr.write_str(fmt!("%?", v)); - } - - fn emit_borrowed_str(&self, v: &str) { - self.wr.write_str(fmt!("&%?", v)); - } - - fn emit_owned_str(&self, v: &str) { - self.wr.write_str(fmt!("~%?", v)); - } - - fn emit_managed_str(&self, v: &str) { - self.wr.write_str(fmt!("@%?", v)); - } - - fn emit_borrowed(&self, f: fn()) { - self.wr.write_str(~"&"); - f(); - } - - fn emit_owned(&self, f: fn()) { - self.wr.write_str(~"~"); - f(); - } - - fn emit_managed(&self, f: fn()) { - self.wr.write_str(~"@"); - f(); - } - - fn emit_enum(&self, _name: &str, f: fn()) { - f(); - } - - fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint, - f: fn()) { - self.wr.write_str(v_name); - if sz > 0u { self.wr.write_str(~"("); } - f(); - if sz > 0u { self.wr.write_str(~")"); } - } - - fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { - if idx > 0u { self.wr.write_str(~", "); } - f(); - } - - fn emit_borrowed_vec(&self, _len: uint, f: fn()) { - self.wr.write_str(~"&["); - f(); - self.wr.write_str(~"]"); - } - - fn emit_owned_vec(&self, _len: uint, f: fn()) { - self.wr.write_str(~"~["); - f(); - self.wr.write_str(~"]"); - } - - fn emit_managed_vec(&self, _len: uint, f: fn()) { - self.wr.write_str(~"@["); - f(); - self.wr.write_str(~"]"); - } - - fn emit_vec_elt(&self, idx: uint, f: fn()) { - if idx > 0u { self.wr.write_str(~", "); } - f(); - } - - fn emit_rec(&self, f: fn()) { - self.wr.write_str(~"{"); - f(); - self.wr.write_str(~"}"); - } - - fn emit_struct(&self, name: &str, f: fn()) { - self.wr.write_str(fmt!("%s {", name)); - f(); - self.wr.write_str(~"}"); - } - - fn emit_field(&self, name: &str, idx: uint, f: fn()) { - if idx > 0u { self.wr.write_str(~", "); } - self.wr.write_str(name); - self.wr.write_str(~": "); - f(); - } - - fn emit_tup(&self, _len: uint, f: fn()) { - self.wr.write_str(~"("); - f(); - self.wr.write_str(~")"); - } - - fn emit_tup_elt(&self, idx: uint, f: fn()) { - if idx > 0u { self.wr.write_str(~", "); } - f(); - } -} +pub use prettyprint::*; diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index 8ba00e65dec..5173ef163a2 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -1,81 +1,530 @@ //! Support code for serialization. -#[allow(deprecated_mode)]; - /* Core serialization interfaces. */ +#[forbid(deprecated_mode)]; +#[forbid(non_camel_case_types)]; + pub trait Serializer { // Primitive types: - fn emit_nil(); - fn emit_uint(v: uint); - fn emit_u64(v: u64); - fn emit_u32(v: u32); - fn emit_u16(v: u16); - fn emit_u8(v: u8); - fn emit_int(v: int); - fn emit_i64(v: i64); - fn emit_i32(v: i32); - fn emit_i16(v: i16); - fn emit_i8(v: i8); - fn emit_bool(v: bool); - fn emit_float(v: float); - fn emit_f64(v: f64); - fn emit_f32(v: f32); - fn emit_str(v: &str); + fn emit_nil(&self); + fn emit_uint(&self, v: uint); + fn emit_u64(&self, v: u64); + fn emit_u32(&self, v: u32); + fn emit_u16(&self, v: u16); + fn emit_u8(&self, v: u8); + fn emit_int(&self, v: int); + fn emit_i64(&self, v: i64); + fn emit_i32(&self, v: i32); + fn emit_i16(&self, v: i16); + fn emit_i8(&self, v: i8); + fn emit_bool(&self, v: bool); + fn emit_float(&self, v: float); + fn emit_f64(&self, v: f64); + fn emit_f32(&self, v: f32); + fn emit_char(&self, v: char); + fn emit_borrowed_str(&self, v: &str); + fn emit_owned_str(&self, v: &str); + fn emit_managed_str(&self, v: &str); // Compound types: - fn emit_enum(name: &str, f: fn()); - fn emit_enum_variant(v_name: &str, v_id: uint, sz: uint, f: fn()); - fn emit_enum_variant_arg(idx: uint, f: fn()); - fn emit_vec(len: uint, f: fn()); - fn emit_vec_elt(idx: uint, f: fn()); - fn emit_box(f: fn()); - fn emit_uniq(f: fn()); - fn emit_rec(f: fn()); - fn emit_rec_field(f_name: &str, f_idx: uint, f: fn()); - fn emit_tup(sz: uint, f: fn()); - fn emit_tup_elt(idx: uint, f: fn()); + fn emit_borrowed(&self, f: fn()); + fn emit_owned(&self, f: fn()); + fn emit_managed(&self, f: fn()); + + fn emit_enum(&self, name: &str, f: fn()); + fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn()); + fn emit_enum_variant_arg(&self, idx: uint, f: fn()); + + fn emit_borrowed_vec(&self, len: uint, f: fn()); + fn emit_owned_vec(&self, len: uint, f: fn()); + fn emit_managed_vec(&self, len: uint, f: fn()); + fn emit_vec_elt(&self, idx: uint, f: fn()); + + fn emit_rec(&self, f: fn()); + fn emit_struct(&self, name: &str, f: fn()); + fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); + + fn emit_tup(&self, len: uint, f: fn()); + fn emit_tup_elt(&self, idx: uint, f: fn()); } pub trait Deserializer { // Primitive types: - fn read_nil() -> (); - - fn read_uint() -> uint; - fn read_u64() -> u64; - fn read_u32() -> u32; - fn read_u16() -> u16; - fn read_u8() -> u8; - - fn read_int() -> int; - fn read_i64() -> i64; - fn read_i32() -> i32; - fn read_i16() -> i16; - fn read_i8() -> i8; - - - fn read_bool() -> bool; - - fn read_str() -> ~str; - - fn read_f64() -> f64; - fn read_f32() -> f32; - fn read_float() -> float; + fn read_nil(&self) -> (); + fn read_uint(&self) -> uint; + fn read_u64(&self) -> u64; + fn read_u32(&self) -> u32; + fn read_u16(&self) -> u16; + fn read_u8(&self) -> u8; + fn read_int(&self) -> int; + fn read_i64(&self) -> i64; + fn read_i32(&self) -> i32; + fn read_i16(&self) -> i16; + fn read_i8(&self) -> i8; + fn read_bool(&self) -> bool; + fn read_f64(&self) -> f64; + fn read_f32(&self) -> f32; + fn read_float(&self) -> float; + fn read_char(&self) -> char; + fn read_owned_str(&self) -> ~str; + fn read_managed_str(&self) -> @str; // Compound types: - fn read_enum(name: &str, f: fn() -> T) -> T; - fn read_enum_variant(f: fn(uint) -> T) -> T; - fn read_enum_variant_arg(idx: uint, f: fn() -> T) -> T; - fn read_vec(f: fn(uint) -> T) -> T; - fn read_vec_elt(idx: uint, f: fn() -> T) -> T; - fn read_box(f: fn() -> T) -> T; - fn read_uniq(f: fn() -> T) -> T; - fn read_rec(f: fn() -> T) -> T; - fn read_rec_field(f_name: &str, f_idx: uint, f: fn() -> T) -> T; - fn read_tup(sz: uint, f: fn() -> T) -> T; - fn read_tup_elt(idx: uint, f: fn() -> T) -> T; + fn read_enum(&self, name: &str, f: fn() -> T) -> T; + fn read_enum_variant(&self, f: fn(uint) -> T) -> T; + fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T; + + fn read_owned(&self, f: fn() -> T) -> T; + fn read_managed(&self, f: fn() -> T) -> T; + + fn read_owned_vec(&self, f: fn(uint) -> T) -> T; + fn read_managed_vec(&self, f: fn(uint) -> T) -> T; + fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T; + + fn read_rec(&self, f: fn() -> T) -> T; + fn read_struct(&self, name: &str, f: fn() -> T) -> T; + fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T; + + fn read_tup(&self, sz: uint, f: fn() -> T) -> T; + fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T; +} + +pub trait Serializable { + fn serialize(&self, s: &S); +} + +pub trait Deserializable { + static fn deserialize(&self, d: &D) -> self; +} + +pub impl uint: Serializable { + fn serialize(&self, s: &S) { s.emit_uint(*self) } +} + +pub impl uint: Deserializable { + static fn deserialize(&self, d: &D) -> uint { + d.read_uint() + } +} + +pub impl u8: Serializable { + fn serialize(&self, s: &S) { s.emit_u8(*self) } +} + +pub impl u8: Deserializable { + static fn deserialize(&self, d: &D) -> u8 { + d.read_u8() + } +} + +pub impl u16: Serializable { + fn serialize(&self, s: &S) { s.emit_u16(*self) } +} + +pub impl u16: Deserializable { + static fn deserialize(&self, d: &D) -> u16 { + d.read_u16() + } +} + +pub impl u32: Serializable { + fn serialize(&self, s: &S) { s.emit_u32(*self) } +} + +pub impl u32: Deserializable { + static fn deserialize(&self, d: &D) -> u32 { + d.read_u32() + } +} + +pub impl u64: Serializable { + fn serialize(&self, s: &S) { s.emit_u64(*self) } +} + +pub impl u64: Deserializable { + static fn deserialize(&self, d: &D) -> u64 { + d.read_u64() + } +} + +pub impl int: Serializable { + fn serialize(&self, s: &S) { s.emit_int(*self) } +} + +pub impl int: Deserializable { + static fn deserialize(&self, d: &D) -> int { + d.read_int() + } +} + +pub impl i8: Serializable { + fn serialize(&self, s: &S) { s.emit_i8(*self) } +} + +pub impl i8: Deserializable { + static fn deserialize(&self, d: &D) -> i8 { + d.read_i8() + } +} + +pub impl i16: Serializable { + fn serialize(&self, s: &S) { s.emit_i16(*self) } +} + +pub impl i16: Deserializable { + static fn deserialize(&self, d: &D) -> i16 { + d.read_i16() + } +} + +pub impl i32: Serializable { + fn serialize(&self, s: &S) { s.emit_i32(*self) } +} + +pub impl i32: Deserializable { + static fn deserialize(&self, d: &D) -> i32 { + d.read_i32() + } +} + +pub impl i64: Serializable { + fn serialize(&self, s: &S) { s.emit_i64(*self) } +} + +pub impl i64: Deserializable { + static fn deserialize(&self, d: &D) -> i64 { + d.read_i64() + } +} + +pub impl &str: Serializable { + fn serialize(&self, s: &S) { s.emit_borrowed_str(*self) } +} + +pub impl ~str: Serializable { + fn serialize(&self, s: &S) { s.emit_owned_str(*self) } +} + +pub impl ~str: Deserializable { + static fn deserialize(&self, d: &D) -> ~str { + d.read_owned_str() + } +} + +pub impl @str: Serializable { + fn serialize(&self, s: &S) { s.emit_managed_str(*self) } +} + +pub impl @str: Deserializable { + static fn deserialize(&self, d: &D) -> @str { + d.read_managed_str() + } +} + +pub impl float: Serializable { + fn serialize(&self, s: &S) { s.emit_float(*self) } +} + +pub impl float: Deserializable { + static fn deserialize(&self, d: &D) -> float { + d.read_float() + } +} + +pub impl f32: Serializable { + fn serialize(&self, s: &S) { s.emit_f32(*self) } +} + +pub impl f32: Deserializable { + static fn deserialize(&self, d: &D) -> f32 { + d.read_f32() } +} + +pub impl f64: Serializable { + fn serialize(&self, s: &S) { s.emit_f64(*self) } +} + +pub impl f64: Deserializable { + static fn deserialize(&self, d: &D) -> f64 { + d.read_f64() + } +} + +pub impl bool: Serializable { + fn serialize(&self, s: &S) { s.emit_bool(*self) } +} + +pub impl bool: Deserializable { + static fn deserialize(&self, d: &D) -> bool { + d.read_bool() + } +} + +pub impl (): Serializable { + fn serialize(&self, s: &S) { s.emit_nil() } +} + +pub impl (): Deserializable { + static fn deserialize(&self, d: &D) -> () { + d.read_nil() + } +} + +pub impl &T: Serializable { + fn serialize(&self, s: &S) { + s.emit_borrowed(|| (**self).serialize(s)) + } +} + +pub impl ~T: Serializable { + fn serialize(&self, s: &S) { + s.emit_owned(|| (**self).serialize(s)) + } +} + +pub impl ~T: Deserializable { + static fn deserialize(&self, d: &D) -> ~T { + d.read_owned(|| ~deserialize(d)) + } +} + +pub impl @T: Serializable { + fn serialize(&self, s: &S) { + s.emit_managed(|| (**self).serialize(s)) + } +} + +pub impl @T: Deserializable { + static fn deserialize(&self, d: &D) -> @T { + d.read_managed(|| @deserialize(d)) + } +} + +pub impl &[T]: Serializable { + fn serialize(&self, s: &S) { + do s.emit_borrowed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl ~[T]: Serializable { + fn serialize(&self, s: &S) { + do s.emit_owned_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl ~[T]: Deserializable { + static fn deserialize(&self, d: &D) -> ~[T] { + do d.read_owned_vec |len| { + do vec::from_fn(len) |i| { + d.read_vec_elt(i, || deserialize(d)) + } + } + } +} + +pub impl @[T]: Serializable { + fn serialize(&self, s: &S) { + do s.emit_managed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl @[T]: Deserializable { + static fn deserialize(&self, d: &D) -> @[T] { + do d.read_managed_vec |len| { + do at_vec::from_fn(len) |i| { + d.read_vec_elt(i, || deserialize(d)) + } + } + } +} + +pub impl Option: Serializable { + fn serialize(&self, s: &S) { + do s.emit_enum(~"option") { + match *self { + None => do s.emit_enum_variant(~"none", 0u, 0u) { + }, + + Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { + s.emit_enum_variant_arg(0u, || v.serialize(s)) + } + } + } + } +} + +pub impl Option: Deserializable { + static fn deserialize(&self, d: &D) -> Option { + do d.read_enum(~"option") { + do d.read_enum_variant |i| { + match i { + 0 => None, + 1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))), + _ => fail(#fmt("Bad variant for option: %u", i)) + } + } + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable +> (T0, T1): Serializable { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1) => { + do s.emit_tup(2) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable +> (T0, T1): Deserializable { + static fn deserialize(&self, d: &D) -> (T0, T1) { + do d.read_tup(2) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable +> (T0, T1, T2): Serializable { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2) => { + do s.emit_tup(3) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable +> (T0, T1, T2): Deserializable { + static fn deserialize(&self, d: &D) -> (T0, T1, T2) { + do d.read_tup(3) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable, + T3: Serializable +> (T0, T1, T2, T3): Serializable { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3) => { + do s.emit_tup(4) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + s.emit_tup_elt(3, || t3.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable, + T3: Deserializable +> (T0, T1, T2, T3): Deserializable { + static fn deserialize(&self, d: &D) -> (T0, T1, T2, T3) { + do d.read_tup(4) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)), + d.read_tup_elt(3, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable, + T3: Serializable, + T4: Serializable +> (T0, T1, T2, T3, T4): Serializable { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3, ref t4) => { + do s.emit_tup(5) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + s.emit_tup_elt(3, || t3.serialize(s)); + s.emit_tup_elt(4, || t4.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable, + T3: Deserializable, + T4: Deserializable +> (T0, T1, T2, T3, T4): Deserializable { + static fn deserialize(&self, d: &D) + -> (T0, T1, T2, T3, T4) { + do d.read_tup(5) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)), + d.read_tup_elt(3, || deserialize(d)), + d.read_tup_elt(4, || deserialize(d)) + ) + } + } } // ___________________________________________________________________________ @@ -83,188 +532,31 @@ pub trait Deserializer { // // In some cases, these should eventually be coded as traits. -pub fn emit_from_vec(&&s: S, &&v: ~[T], f: fn(&&x: T)) { - do s.emit_vec(vec::len(v)) { - for vec::eachi(v) |i,e| { - do s.emit_vec_elt(i) { - f(*e) +pub trait SerializerHelpers { + fn emit_from_vec(&self, v: &[T], f: fn(&T)); +} + +pub impl S: SerializerHelpers { + fn emit_from_vec(&self, v: &[T], f: fn(&T)) { + do self.emit_owned_vec(v.len()) { + for v.eachi |i, e| { + do self.emit_vec_elt(i) { + f(e) + } } } } } -pub fn read_to_vec(&&d: D, f: fn() -> T) -> ~[T] { - do d.read_vec |len| { - do vec::from_fn(len) |i| { - d.read_vec_elt(i, || f()) - } - } -} - -pub trait SerializerHelpers { - fn emit_from_vec(&&v: ~[T], f: fn(&&x: T)); -} - -impl S: SerializerHelpers { - fn emit_from_vec(&&v: ~[T], f: fn(&&x: T)) { - emit_from_vec(self, v, f) - } -} - pub trait DeserializerHelpers { - fn read_to_vec(f: fn() -> T) -> ~[T]; + fn read_to_vec(&self, f: fn() -> T) -> ~[T]; } -impl D: DeserializerHelpers { - fn read_to_vec(f: fn() -> T) -> ~[T] { - read_to_vec(self, f) - } -} - -pub fn serialize_uint(&&s: S, v: uint) { - s.emit_uint(v); -} - -pub fn deserialize_uint(&&d: D) -> uint { - d.read_uint() -} - -pub fn serialize_u8(&&s: S, v: u8) { - s.emit_u8(v); -} - -pub fn deserialize_u8(&&d: D) -> u8 { - d.read_u8() -} - -pub fn serialize_u16(&&s: S, v: u16) { - s.emit_u16(v); -} - -pub fn deserialize_u16(&&d: D) -> u16 { - d.read_u16() -} - -pub fn serialize_u32(&&s: S, v: u32) { - s.emit_u32(v); -} - -pub fn deserialize_u32(&&d: D) -> u32 { - d.read_u32() -} - -pub fn serialize_u64(&&s: S, v: u64) { - s.emit_u64(v); -} - -pub fn deserialize_u64(&&d: D) -> u64 { - d.read_u64() -} - -pub fn serialize_int(&&s: S, v: int) { - s.emit_int(v); -} - -pub fn deserialize_int(&&d: D) -> int { - d.read_int() -} - -pub fn serialize_i8(&&s: S, v: i8) { - s.emit_i8(v); -} - -pub fn deserialize_i8(&&d: D) -> i8 { - d.read_i8() -} - -pub fn serialize_i16(&&s: S, v: i16) { - s.emit_i16(v); -} - -pub fn deserialize_i16(&&d: D) -> i16 { - d.read_i16() -} - -pub fn serialize_i32(&&s: S, v: i32) { - s.emit_i32(v); -} - -pub fn deserialize_i32(&&d: D) -> i32 { - d.read_i32() -} - -pub fn serialize_i64(&&s: S, v: i64) { - s.emit_i64(v); -} - -pub fn deserialize_i64(&&d: D) -> i64 { - d.read_i64() -} - -pub fn serialize_str(&&s: S, v: &str) { - s.emit_str(v); -} - -pub fn deserialize_str(&&d: D) -> ~str { - d.read_str() -} - -pub fn serialize_float(&&s: S, v: float) { - s.emit_float(v); -} - -pub fn deserialize_float(&&d: D) -> float { - d.read_float() -} - -pub fn serialize_f32(&&s: S, v: f32) { - s.emit_f32(v); -} - -pub fn deserialize_f32(&&d: D) -> f32 { - d.read_f32() -} - -pub fn serialize_f64(&&s: S, v: f64) { - s.emit_f64(v); -} - -pub fn deserialize_f64(&&d: D) -> f64 { - d.read_f64() -} - -pub fn serialize_bool(&&s: S, v: bool) { - s.emit_bool(v); -} - -pub fn deserialize_bool(&&d: D) -> bool { - d.read_bool() -} - -pub fn serialize_Option(&&s: S, &&v: Option, - st: fn(&&x: T)) { - do s.emit_enum(~"option") { - match v { - None => do s.emit_enum_variant(~"none", 0u, 0u) { - }, - - Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { - do s.emit_enum_variant_arg(0u) { - st(*v) - } - } - } - } -} - -pub fn deserialize_Option(&&d: D, st: fn() -> T) - -> Option { - do d.read_enum(~"option") { - do d.read_enum_variant |i| { - match i { - 0 => None, - 1 => Some(d.read_enum_variant_arg(0u, || st() )), - _ => fail(#fmt("Bad variant for option: %u", i)) +pub impl D: DeserializerHelpers { + fn read_to_vec(&self, f: fn() -> T) -> ~[T] { + do self.read_owned_vec |len| { + do vec::from_fn(len) |i| { + self.read_vec_elt(i, || f()) } } } diff --git a/src/libstd/serialization2.rs b/src/libstd/serialization2.rs index 5173ef163a2..9ea54477869 100644 --- a/src/libstd/serialization2.rs +++ b/src/libstd/serialization2.rs @@ -4,560 +4,4 @@ Core serialization interfaces. */ -#[forbid(deprecated_mode)]; -#[forbid(non_camel_case_types)]; - -pub trait Serializer { - // Primitive types: - fn emit_nil(&self); - fn emit_uint(&self, v: uint); - fn emit_u64(&self, v: u64); - fn emit_u32(&self, v: u32); - fn emit_u16(&self, v: u16); - fn emit_u8(&self, v: u8); - fn emit_int(&self, v: int); - fn emit_i64(&self, v: i64); - fn emit_i32(&self, v: i32); - fn emit_i16(&self, v: i16); - fn emit_i8(&self, v: i8); - fn emit_bool(&self, v: bool); - fn emit_float(&self, v: float); - fn emit_f64(&self, v: f64); - fn emit_f32(&self, v: f32); - fn emit_char(&self, v: char); - fn emit_borrowed_str(&self, v: &str); - fn emit_owned_str(&self, v: &str); - fn emit_managed_str(&self, v: &str); - - // Compound types: - fn emit_borrowed(&self, f: fn()); - fn emit_owned(&self, f: fn()); - fn emit_managed(&self, f: fn()); - - fn emit_enum(&self, name: &str, f: fn()); - fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn()); - fn emit_enum_variant_arg(&self, idx: uint, f: fn()); - - fn emit_borrowed_vec(&self, len: uint, f: fn()); - fn emit_owned_vec(&self, len: uint, f: fn()); - fn emit_managed_vec(&self, len: uint, f: fn()); - fn emit_vec_elt(&self, idx: uint, f: fn()); - - fn emit_rec(&self, f: fn()); - fn emit_struct(&self, name: &str, f: fn()); - fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); - - fn emit_tup(&self, len: uint, f: fn()); - fn emit_tup_elt(&self, idx: uint, f: fn()); -} - -pub trait Deserializer { - // Primitive types: - fn read_nil(&self) -> (); - fn read_uint(&self) -> uint; - fn read_u64(&self) -> u64; - fn read_u32(&self) -> u32; - fn read_u16(&self) -> u16; - fn read_u8(&self) -> u8; - fn read_int(&self) -> int; - fn read_i64(&self) -> i64; - fn read_i32(&self) -> i32; - fn read_i16(&self) -> i16; - fn read_i8(&self) -> i8; - fn read_bool(&self) -> bool; - fn read_f64(&self) -> f64; - fn read_f32(&self) -> f32; - fn read_float(&self) -> float; - fn read_char(&self) -> char; - fn read_owned_str(&self) -> ~str; - fn read_managed_str(&self) -> @str; - - // Compound types: - fn read_enum(&self, name: &str, f: fn() -> T) -> T; - fn read_enum_variant(&self, f: fn(uint) -> T) -> T; - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T; - - fn read_owned(&self, f: fn() -> T) -> T; - fn read_managed(&self, f: fn() -> T) -> T; - - fn read_owned_vec(&self, f: fn(uint) -> T) -> T; - fn read_managed_vec(&self, f: fn(uint) -> T) -> T; - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T; - - fn read_rec(&self, f: fn() -> T) -> T; - fn read_struct(&self, name: &str, f: fn() -> T) -> T; - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T; - - fn read_tup(&self, sz: uint, f: fn() -> T) -> T; - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T; -} - -pub trait Serializable { - fn serialize(&self, s: &S); -} - -pub trait Deserializable { - static fn deserialize(&self, d: &D) -> self; -} - -pub impl uint: Serializable { - fn serialize(&self, s: &S) { s.emit_uint(*self) } -} - -pub impl uint: Deserializable { - static fn deserialize(&self, d: &D) -> uint { - d.read_uint() - } -} - -pub impl u8: Serializable { - fn serialize(&self, s: &S) { s.emit_u8(*self) } -} - -pub impl u8: Deserializable { - static fn deserialize(&self, d: &D) -> u8 { - d.read_u8() - } -} - -pub impl u16: Serializable { - fn serialize(&self, s: &S) { s.emit_u16(*self) } -} - -pub impl u16: Deserializable { - static fn deserialize(&self, d: &D) -> u16 { - d.read_u16() - } -} - -pub impl u32: Serializable { - fn serialize(&self, s: &S) { s.emit_u32(*self) } -} - -pub impl u32: Deserializable { - static fn deserialize(&self, d: &D) -> u32 { - d.read_u32() - } -} - -pub impl u64: Serializable { - fn serialize(&self, s: &S) { s.emit_u64(*self) } -} - -pub impl u64: Deserializable { - static fn deserialize(&self, d: &D) -> u64 { - d.read_u64() - } -} - -pub impl int: Serializable { - fn serialize(&self, s: &S) { s.emit_int(*self) } -} - -pub impl int: Deserializable { - static fn deserialize(&self, d: &D) -> int { - d.read_int() - } -} - -pub impl i8: Serializable { - fn serialize(&self, s: &S) { s.emit_i8(*self) } -} - -pub impl i8: Deserializable { - static fn deserialize(&self, d: &D) -> i8 { - d.read_i8() - } -} - -pub impl i16: Serializable { - fn serialize(&self, s: &S) { s.emit_i16(*self) } -} - -pub impl i16: Deserializable { - static fn deserialize(&self, d: &D) -> i16 { - d.read_i16() - } -} - -pub impl i32: Serializable { - fn serialize(&self, s: &S) { s.emit_i32(*self) } -} - -pub impl i32: Deserializable { - static fn deserialize(&self, d: &D) -> i32 { - d.read_i32() - } -} - -pub impl i64: Serializable { - fn serialize(&self, s: &S) { s.emit_i64(*self) } -} - -pub impl i64: Deserializable { - static fn deserialize(&self, d: &D) -> i64 { - d.read_i64() - } -} - -pub impl &str: Serializable { - fn serialize(&self, s: &S) { s.emit_borrowed_str(*self) } -} - -pub impl ~str: Serializable { - fn serialize(&self, s: &S) { s.emit_owned_str(*self) } -} - -pub impl ~str: Deserializable { - static fn deserialize(&self, d: &D) -> ~str { - d.read_owned_str() - } -} - -pub impl @str: Serializable { - fn serialize(&self, s: &S) { s.emit_managed_str(*self) } -} - -pub impl @str: Deserializable { - static fn deserialize(&self, d: &D) -> @str { - d.read_managed_str() - } -} - -pub impl float: Serializable { - fn serialize(&self, s: &S) { s.emit_float(*self) } -} - -pub impl float: Deserializable { - static fn deserialize(&self, d: &D) -> float { - d.read_float() - } -} - -pub impl f32: Serializable { - fn serialize(&self, s: &S) { s.emit_f32(*self) } -} - -pub impl f32: Deserializable { - static fn deserialize(&self, d: &D) -> f32 { - d.read_f32() } -} - -pub impl f64: Serializable { - fn serialize(&self, s: &S) { s.emit_f64(*self) } -} - -pub impl f64: Deserializable { - static fn deserialize(&self, d: &D) -> f64 { - d.read_f64() - } -} - -pub impl bool: Serializable { - fn serialize(&self, s: &S) { s.emit_bool(*self) } -} - -pub impl bool: Deserializable { - static fn deserialize(&self, d: &D) -> bool { - d.read_bool() - } -} - -pub impl (): Serializable { - fn serialize(&self, s: &S) { s.emit_nil() } -} - -pub impl (): Deserializable { - static fn deserialize(&self, d: &D) -> () { - d.read_nil() - } -} - -pub impl &T: Serializable { - fn serialize(&self, s: &S) { - s.emit_borrowed(|| (**self).serialize(s)) - } -} - -pub impl ~T: Serializable { - fn serialize(&self, s: &S) { - s.emit_owned(|| (**self).serialize(s)) - } -} - -pub impl ~T: Deserializable { - static fn deserialize(&self, d: &D) -> ~T { - d.read_owned(|| ~deserialize(d)) - } -} - -pub impl @T: Serializable { - fn serialize(&self, s: &S) { - s.emit_managed(|| (**self).serialize(s)) - } -} - -pub impl @T: Deserializable { - static fn deserialize(&self, d: &D) -> @T { - d.read_managed(|| @deserialize(d)) - } -} - -pub impl &[T]: Serializable { - fn serialize(&self, s: &S) { - do s.emit_borrowed_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl ~[T]: Serializable { - fn serialize(&self, s: &S) { - do s.emit_owned_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl ~[T]: Deserializable { - static fn deserialize(&self, d: &D) -> ~[T] { - do d.read_owned_vec |len| { - do vec::from_fn(len) |i| { - d.read_vec_elt(i, || deserialize(d)) - } - } - } -} - -pub impl @[T]: Serializable { - fn serialize(&self, s: &S) { - do s.emit_managed_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl @[T]: Deserializable { - static fn deserialize(&self, d: &D) -> @[T] { - do d.read_managed_vec |len| { - do at_vec::from_fn(len) |i| { - d.read_vec_elt(i, || deserialize(d)) - } - } - } -} - -pub impl Option: Serializable { - fn serialize(&self, s: &S) { - do s.emit_enum(~"option") { - match *self { - None => do s.emit_enum_variant(~"none", 0u, 0u) { - }, - - Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { - s.emit_enum_variant_arg(0u, || v.serialize(s)) - } - } - } - } -} - -pub impl Option: Deserializable { - static fn deserialize(&self, d: &D) -> Option { - do d.read_enum(~"option") { - do d.read_enum_variant |i| { - match i { - 0 => None, - 1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))), - _ => fail(#fmt("Bad variant for option: %u", i)) - } - } - } - } -} - -pub impl< - T0: Serializable, - T1: Serializable -> (T0, T1): Serializable { - fn serialize(&self, s: &S) { - match *self { - (ref t0, ref t1) => { - do s.emit_tup(2) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - } - } - } - } -} - -pub impl< - T0: Deserializable, - T1: Deserializable -> (T0, T1): Deserializable { - static fn deserialize(&self, d: &D) -> (T0, T1) { - do d.read_tup(2) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)) - ) - } - } -} - -pub impl< - T0: Serializable, - T1: Serializable, - T2: Serializable -> (T0, T1, T2): Serializable { - fn serialize(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2) => { - do s.emit_tup(3) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - } - } - } - } -} - -pub impl< - T0: Deserializable, - T1: Deserializable, - T2: Deserializable -> (T0, T1, T2): Deserializable { - static fn deserialize(&self, d: &D) -> (T0, T1, T2) { - do d.read_tup(3) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)) - ) - } - } -} - -pub impl< - T0: Serializable, - T1: Serializable, - T2: Serializable, - T3: Serializable -> (T0, T1, T2, T3): Serializable { - fn serialize(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2, ref t3) => { - do s.emit_tup(4) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - s.emit_tup_elt(3, || t3.serialize(s)); - } - } - } - } -} - -pub impl< - T0: Deserializable, - T1: Deserializable, - T2: Deserializable, - T3: Deserializable -> (T0, T1, T2, T3): Deserializable { - static fn deserialize(&self, d: &D) -> (T0, T1, T2, T3) { - do d.read_tup(4) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)), - d.read_tup_elt(3, || deserialize(d)) - ) - } - } -} - -pub impl< - T0: Serializable, - T1: Serializable, - T2: Serializable, - T3: Serializable, - T4: Serializable -> (T0, T1, T2, T3, T4): Serializable { - fn serialize(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2, ref t3, ref t4) => { - do s.emit_tup(5) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - s.emit_tup_elt(3, || t3.serialize(s)); - s.emit_tup_elt(4, || t4.serialize(s)); - } - } - } - } -} - -pub impl< - T0: Deserializable, - T1: Deserializable, - T2: Deserializable, - T3: Deserializable, - T4: Deserializable -> (T0, T1, T2, T3, T4): Deserializable { - static fn deserialize(&self, d: &D) - -> (T0, T1, T2, T3, T4) { - do d.read_tup(5) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)), - d.read_tup_elt(3, || deserialize(d)), - d.read_tup_elt(4, || deserialize(d)) - ) - } - } -} - -// ___________________________________________________________________________ -// Helper routines -// -// In some cases, these should eventually be coded as traits. - -pub trait SerializerHelpers { - fn emit_from_vec(&self, v: &[T], f: fn(&T)); -} - -pub impl S: SerializerHelpers { - fn emit_from_vec(&self, v: &[T], f: fn(&T)) { - do self.emit_owned_vec(v.len()) { - for v.eachi |i, e| { - do self.emit_vec_elt(i) { - f(e) - } - } - } - } -} - -pub trait DeserializerHelpers { - fn read_to_vec(&self, f: fn() -> T) -> ~[T]; -} - -pub impl D: DeserializerHelpers { - fn read_to_vec(&self, f: fn() -> T) -> ~[T] { - do self.read_owned_vec |len| { - do vec::from_fn(len) |i| { - self.read_vec_elt(i, || f()) - } - } - } -} +pub use serialization::*; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1c279f81cc3..a27336097d0 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1,9 +1,9 @@ // The Rust abstract syntax tree. -use std::serialization2::{Serializable, - Deserializable, - Serializer, - Deserializer}; +use std::serialization::{Serializable, + Deserializable, + Serializer, + Deserializer}; use codemap::{span, filename}; use parse::token; @@ -18,8 +18,8 @@ impl span: Deserializable { } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type spanned = {node: T, span: span}; @@ -74,8 +74,8 @@ impl ident: to_bytes::IterBytes { // Functions may or may not have names. type fn_ident = Option; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type path = {span: span, global: bool, idents: ~[ident], @@ -86,8 +86,8 @@ type crate_num = int; type node_id = int; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type def_id = {crate: crate_num, node: node_id}; impl def_id : cmp::Eq { @@ -100,8 +100,8 @@ impl def_id : cmp::Eq { const local_crate: crate_num = 0; const crate_node_id: node_id = 0; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum ty_param_bound { bound_copy, bound_send, @@ -110,12 +110,12 @@ enum ty_param_bound { bound_trait(@ty), } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type ty_param = {ident: ident, id: node_id, bounds: @~[ty_param_bound]}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum def { def_fn(def_id, purity), def_static_method(def_id, purity), @@ -294,8 +294,8 @@ type crate_directive = spanned; type meta_item = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum meta_item_ { meta_word(~str), meta_list(~str, ~[@meta_item]), @@ -304,24 +304,24 @@ enum meta_item_ { type blk = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type blk_ = {view_items: ~[@view_item], stmts: ~[@stmt], expr: Option<@expr>, id: node_id, rules: blk_check_mode}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type pat = {id: node_id, node: pat_, span: span}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type field_pat = {ident: ident, pat: @pat}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum binding_mode { bind_by_value, bind_by_move, @@ -377,8 +377,8 @@ impl binding_mode : cmp::Eq { pure fn ne(other: &binding_mode) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum pat_ { pat_wild, // A pat_ident may either be a new bound variable, @@ -401,8 +401,8 @@ enum pat_ { pat_range(@expr, @expr), } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum mutability { m_mutbl, m_imm, m_const, } impl mutability : to_bytes::IterBytes { @@ -418,8 +418,8 @@ impl mutability : cmp::Eq { pure fn ne(other: &mutability) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum proto { proto_bare, // foreign fn proto_uniq, // fn~ @@ -434,8 +434,8 @@ impl proto : cmp::Eq { pure fn ne(other: &proto) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum vstore { // FIXME (#2112): Change uint to @expr (actually only constant exprs) vstore_fixed(Option), // [1,2,3,4]/_ or 4 @@ -444,8 +444,8 @@ enum vstore { vstore_slice(@region) // &[1,2,3,4](foo)? } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum expr_vstore { // FIXME (#2112): Change uint to @expr (actually only constant exprs) expr_vstore_fixed(Option), // [1,2,3,4]/_ or 4 @@ -461,8 +461,8 @@ pure fn is_blockish(p: ast::proto) -> bool { } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum binop { add, subtract, @@ -491,8 +491,8 @@ impl binop : cmp::Eq { pure fn ne(other: &binop) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum unop { box(mutability), uniq(mutability), @@ -543,8 +543,8 @@ impl unop : cmp::Eq { // Generally, after typeck you can get the inferred value // using ty::resolved_T(...). -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum inferable { expl(T), infer(node_id) @@ -583,8 +583,8 @@ impl inferable : cmp::Eq { } // "resolved" mode: the real modes. -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum rmode { by_ref, by_val, by_move, by_copy } impl rmode : to_bytes::IterBytes { @@ -606,8 +606,8 @@ type mode = inferable; type stmt = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum stmt_ { stmt_decl(@decl, node_id), @@ -618,8 +618,8 @@ enum stmt_ { stmt_semi(@expr, node_id), } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum init_op { init_assign, init_move, } impl init_op : cmp::Eq { @@ -642,14 +642,14 @@ impl init_op : cmp::Eq { pure fn ne(other: &init_op) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type initializer = {op: init_op, expr: @expr}; // FIXME (pending discussion of #1697, #2178...): local should really be // a refinement on pat. -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type local_ = {is_mutbl: bool, ty: @ty, pat: @pat, init: Option, id: node_id}; @@ -657,22 +657,22 @@ type local = spanned; type decl = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum decl_ { decl_local(~[@local]), decl_item(@item), } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type arm = {pats: ~[@pat], guard: Option<@expr>, body: blk}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type field_ = {mutbl: mutability, ident: ident, expr: @expr}; type field = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum blk_check_mode { default_blk, unsafe_blk, } impl blk_check_mode : cmp::Eq { @@ -687,22 +687,22 @@ impl blk_check_mode : cmp::Eq { pure fn ne(other: &blk_check_mode) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type expr = {id: node_id, callee_id: node_id, node: expr_, span: span}; // Extra node ID is only used for index, assign_op, unary, binary -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum log_level { error, debug, other } // 0 = error, 1 = debug, 2 = other -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum alt_mode { alt_check, alt_exhaustive, } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum expr_ { expr_vstore(@expr, expr_vstore), expr_vec(~[@expr], mutability), @@ -758,8 +758,8 @@ enum expr_ { expr_repeat(@expr /* element */, @expr /* count */, mutability) } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type capture_item_ = { id: int, is_move: bool, @@ -787,8 +787,8 @@ type capture_clause = @~[capture_item]; // else knows what to do with them, so you'll probably get a syntax // error. // -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] #[doc="For macro invocations; parsing is delegated to the macro"] enum token_tree { tt_tok(span, token::token), @@ -852,8 +852,8 @@ enum token_tree { // type matcher = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum matcher_ { // match one token match_tok(token::token), @@ -868,14 +868,14 @@ type mac = spanned; type mac_arg = Option<@expr>; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type mac_body_ = {span: span}; type mac_body = Option; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum mac_ { mac_invoc(@path, mac_arg, mac_body), // old macro-invocation mac_invoc_tt(@path,~[token_tree]), // new macro-invocation @@ -888,8 +888,8 @@ enum mac_ { type lit = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum lit_ { lit_str(@~str), lit_int(i64, int_ty), @@ -930,24 +930,24 @@ impl ast::lit_: cmp::Eq { // NB: If you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type mt = {ty: @ty, mutbl: mutability}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type ty_field_ = {ident: ident, mt: mt}; type ty_field = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type ty_method = {ident: ident, attrs: ~[attribute], purity: purity, decl: fn_decl, tps: ~[ty_param], self_ty: self_ty, id: node_id, span: span}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] // A trait method is either required (meaning it doesn't have an // implementation, just a signature) or provided (meaning it has a default // implementation). @@ -956,8 +956,8 @@ enum trait_method { provided(@method), } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } impl int_ty : to_bytes::IterBytes { @@ -986,8 +986,8 @@ impl int_ty : cmp::Eq { pure fn ne(other: &int_ty) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } impl uint_ty : to_bytes::IterBytes { @@ -1014,8 +1014,8 @@ impl uint_ty : cmp::Eq { pure fn ne(other: &uint_ty) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum float_ty { ty_f, ty_f32, ty_f64, } impl float_ty : to_bytes::IterBytes { @@ -1033,13 +1033,13 @@ impl float_ty : cmp::Eq { pure fn ne(other: &float_ty) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type ty = {id: node_id, node: ty_, span: span}; // Not represented directly in the AST, referred to by name through a ty_path. -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum prim_ty { ty_int(int_ty), ty_uint(uint_ty), @@ -1086,12 +1086,12 @@ impl prim_ty : cmp::Eq { pure fn ne(other: &prim_ty) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type region = {id: node_id, node: region_}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum region_ { re_anon, re_static, @@ -1099,8 +1099,8 @@ enum region_ { re_named(ident) } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum ty_ { ty_nil, ty_bot, /* bottom type */ @@ -1139,19 +1139,19 @@ impl ty : to_bytes::IterBytes { } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type arg = {mode: mode, ty: @ty, ident: ident, id: node_id}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type fn_decl = {inputs: ~[arg], output: @ty, cf: ret_style}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum purity { pure_fn, // declared with "pure fn" unsafe_fn, // declared with "unsafe fn" @@ -1172,8 +1172,8 @@ impl purity : cmp::Eq { pure fn ne(other: &purity) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum ret_style { noreturn, // functions with return type _|_ that always // raise an error or exit (i.e. never return to the caller) @@ -1198,8 +1198,8 @@ impl ret_style : cmp::Eq { pure fn ne(other: &ret_style) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum self_ty_ { sty_static, // no self: static method sty_by_ref, // old by-reference self: `` @@ -1255,20 +1255,20 @@ impl self_ty_ : cmp::Eq { type self_ty = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type method = {ident: ident, attrs: ~[attribute], tps: ~[ty_param], self_ty: self_ty, purity: purity, decl: fn_decl, body: blk, id: node_id, span: span, self_id: node_id, vis: visibility}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type _mod = {view_items: ~[@view_item], items: ~[@item]}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum foreign_abi { foreign_abi_rust_intrinsic, foreign_abi_cdecl, @@ -1276,8 +1276,8 @@ enum foreign_abi { } // Foreign mods can be named or anonymous -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum foreign_mod_sort { named, anonymous } impl foreign_mod_sort : cmp::Eq { @@ -1301,48 +1301,48 @@ impl foreign_abi : cmp::Eq { pure fn ne(other: &foreign_abi) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type foreign_mod = {sort: foreign_mod_sort, view_items: ~[@view_item], items: ~[@foreign_item]}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type variant_arg = {ty: @ty, id: node_id}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum variant_kind { tuple_variant_kind(~[variant_arg]), struct_variant_kind(@struct_def), enum_variant_kind(enum_def) } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type enum_def_ = { variants: ~[variant], common: Option<@struct_def> }; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum enum_def = enum_def_; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind, id: node_id, disr_expr: Option<@expr>, vis: visibility}; type variant = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type path_list_ident_ = {name: ident, id: node_id}; type path_list_ident = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum namespace { module_ns, type_value_ns } impl namespace : cmp::Eq { @@ -1354,8 +1354,8 @@ impl namespace : cmp::Eq { type view_path = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum view_path_ { // quux = foo::bar::baz @@ -1372,13 +1372,13 @@ enum view_path_ { view_path_list(@path, ~[path_list_ident], node_id) } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type view_item = {node: view_item_, attrs: ~[attribute], vis: visibility, span: span}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum view_item_ { view_item_use(ident, ~[@meta_item], node_id), view_item_import(~[@view_path]), @@ -1391,8 +1391,8 @@ type attribute = spanned; // Distinguishes between attributes that decorate items and attributes that // are contained as statements within items. These two cases need to be // distinguished for pretty-printing. -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum attr_style { attr_outer, attr_inner, } impl attr_style : cmp::Eq { @@ -1403,8 +1403,8 @@ impl attr_style : cmp::Eq { } // doc-comments are promoted to attributes that have is_sugared_doc = true -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type attribute_ = {style: attr_style, value: meta_item, is_sugared_doc: bool}; /* @@ -1416,12 +1416,12 @@ type attribute_ = {style: attr_style, value: meta_item, is_sugared_doc: bool}; conceptually, the impl_id stands in for the pair of (this class, this trait) */ -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type trait_ref = {path: @path, ref_id: node_id, impl_id: node_id}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum visibility { public, private, inherited } impl visibility : cmp::Eq { @@ -1438,8 +1438,8 @@ impl visibility : cmp::Eq { pure fn ne(other: &visibility) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type struct_field_ = { kind: struct_field_kind, id: node_id, @@ -1448,15 +1448,15 @@ type struct_field_ = { type struct_field = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum struct_field_kind { named_field(ident, class_mutability, visibility), unnamed_field // element of a tuple-like struct } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type struct_def = { traits: ~[@trait_ref], /* traits this struct implements */ fields: ~[@struct_field], /* fields */ @@ -1472,14 +1472,14 @@ type struct_def = { FIXME (#3300): Should allow items to be anonymous. Right now we just use dummy names for anon items. */ -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type item = {ident: ident, attrs: ~[attribute], id: node_id, node: item_, vis: visibility, span: span}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum item_ { item_const(@ty, @expr), item_fn(fn_decl, purity, ~[ty_param], blk), @@ -1496,8 +1496,8 @@ enum item_ { item_mac(mac), } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum class_mutability { class_mutable, class_immutable } impl class_mutability : to_bytes::IterBytes { @@ -1520,8 +1520,8 @@ impl class_mutability : cmp::Eq { type class_ctor = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type class_ctor_ = {id: node_id, attrs: ~[attribute], self_id: node_id, @@ -1530,15 +1530,15 @@ type class_ctor_ = {id: node_id, type class_dtor = spanned; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type class_dtor_ = {id: node_id, attrs: ~[attribute], self_id: node_id, body: blk}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type foreign_item = {ident: ident, attrs: ~[attribute], @@ -1547,8 +1547,8 @@ type foreign_item = span: span, vis: visibility}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum foreign_item_ { foreign_item_fn(fn_decl, purity, ~[ty_param]), foreign_item_const(@ty) @@ -1557,8 +1557,8 @@ enum foreign_item_ { // The data we save and restore about an inlined item or method. This is not // part of the AST that we parse from a file, but it becomes part of the tree // that we trans. -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum inlined_item { ii_item(@item), ii_method(def_id /* impl id */, @method), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 47cbdb7ac6c..ab24d7a5316 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -406,8 +406,8 @@ fn dtor_dec() -> fn_decl { // ______________________________________________________________________ // Enumerating the IDs which appear in an AST -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type id_range = {min: node_id, max: node_id}; fn empty(range: id_range) -> bool { diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index 63a6551bf88..b06536f4e02 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -1,62 +1,64 @@ /* -The compiler code necessary to implement the #[auto_serialize] -extension. The idea here is that type-defining items may be tagged -with #[auto_serialize], which will cause us to generate a little -companion module with the same name as the item. +The compiler code necessary to implement the #[auto_serialize] and +#[auto_deserialize] extension. The idea here is that type-defining items may +be tagged with #[auto_serialize] and #[auto_deserialize], which will cause +us to generate a little companion module with the same name as the item. For example, a type like: - type node_id = uint; + #[auto_serialize] + #[auto_deserialize] + struct Node {id: uint} -would generate two functions like: +would generate two implementations like: - fn serialize_node_id(s: S, v: node_id) { - s.emit_uint(v); + impl Node: Serializable { + fn serialize(s: &S) { + do s.emit_struct("Node") { + s.emit_field("id", 0, || s.emit_uint(self)) + } + } } - fn deserialize_node_id(d: D) -> node_id { - d.read_uint() + + impl node_id: Deserializable { + static fn deserialize(d: &D) -> Node { + do d.read_struct("Node") { + Node { + id: d.read_field(~"x", 0, || deserialize(d)) + } + } + } } Other interesting scenarios are whe the item has type parameters or references other non-built-in types. A type definition like: + #[auto_serialize] + #[auto_deserialize] type spanned = {node: T, span: span}; would yield functions like: - fn serialize_spanned(s: S, v: spanned, t: fn(T)) { - s.emit_rec(2u) {|| - s.emit_rec_field("node", 0u) {|| - t(s.node); - }; - s.emit_rec_field("span", 1u) {|| - serialize_span(s, s.span); - }; - } - } - fn deserialize_spanned(d: D, t: fn() -> T) -> node_id { - d.read_rec(2u) {|| - {node: d.read_rec_field("node", 0u, t), - span: d.read_rec_field("span", 1u) {||deserialize_span(d)}} - } + impl spanned: Serializable { + fn serialize(s: &S) { + do s.emit_rec { + s.emit_field("node", 0, || self.node.serialize(s)); + s.emit_field("span", 1, || self.span.serialize(s)); + } + } } -In general, the code to serialize an instance `v` of a non-built-in -type a::b::c looks like: - - a::b::serialize_c(s, {|v| c_T0}, ..., {|v| c_Tn}, v) - -where `c_Ti` is the code to serialize an instance `v` of the type -`Ti`. - -Similarly, the code to deserialize an instance of a non-built-in type -`a::b::c` using the deserializer `d` looks like: - - a::b::deserialize_c(d, {|| c_T0}, ..., {|| c_Tn}) - -where `c_Ti` is the code to deserialize an instance of `Ti` using the -deserializer `d`. + impl spanned: Deserializable { + static fn deserialize(d: &D) -> spanned { + do d.read_rec { + { + node: d.read_field(~"node", 0, || deserialize(d)), + span: d.read_field(~"span", 1, || deserialize(d)), + } + } + } + } FIXME (#2810)--Hygiene. Search for "__" strings. We also assume "std" is the standard library. @@ -69,788 +71,1035 @@ into the tree. This is intended to prevent us from inserting the same node twice. */ + use base::*; use codemap::span; use std::map; use std::map::HashMap; -export expand; +export expand_auto_serialize; +export expand_auto_deserialize; // Transitional reexports so qquote can find the paths it is looking for mod syntax { - #[legacy_exports]; pub use ext; pub use parse; } -type ser_tps_map = map::HashMap ~[@ast::stmt]>; -type deser_tps_map = map::HashMap @ast::expr>; - -fn expand(cx: ext_ctxt, - span: span, - _mitem: ast::meta_item, - in_items: ~[@ast::item]) -> ~[@ast::item] { - fn not_auto_serialize(a: &ast::attribute) -> bool { - attr::get_attr_name(*a) != ~"auto_serialize" +fn expand_auto_serialize( + cx: ext_ctxt, + span: span, + _mitem: ast::meta_item, + in_items: ~[@ast::item] +) -> ~[@ast::item] { + fn is_auto_serialize(a: &ast::attribute) -> bool { + attr::get_attr_name(*a) == ~"auto_serialize" } fn filter_attrs(item: @ast::item) -> @ast::item { - @{attrs: vec::filter(item.attrs, not_auto_serialize), + @{attrs: vec::filter(item.attrs, |a| !is_auto_serialize(a)), .. *item} } - do vec::flat_map(in_items) |in_item| { - match in_item.node { - ast::item_ty(ty, tps) => { - vec::append(~[filter_attrs(*in_item)], - ty_fns(cx, in_item.ident, ty, tps)) - } + do vec::flat_map(in_items) |item| { + if item.attrs.any(is_auto_serialize) { + match item.node { + ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => { + let ser_impl = mk_rec_ser_impl( + cx, + item.span, + item.ident, + fields, + tps + ); - ast::item_enum(enum_definition, tps) => { - vec::append(~[filter_attrs(*in_item)], - enum_fns(cx, in_item.ident, - in_item.span, enum_definition.variants, tps)) - } + ~[filter_attrs(*item), ser_impl] + }, + ast::item_class(@{ fields, _}, tps) => { + let ser_impl = mk_struct_ser_impl( + cx, + item.span, + item.ident, + fields, + tps + ); - _ => { - cx.span_err(span, ~"#[auto_serialize] can only be \ - applied to type and enum \ - definitions"); - ~[*in_item] - } + ~[filter_attrs(*item), ser_impl] + }, + ast::item_enum(enum_def, tps) => { + let ser_impl = mk_enum_ser_impl( + cx, + item.span, + item.ident, + enum_def, + tps + ); + + ~[filter_attrs(*item), ser_impl] + }, + _ => { + cx.span_err(span, ~"#[auto_serialize] can only be \ + applied to structs, record types, \ + and enum definitions"); + ~[*item] + } + } + } else { + ~[*item] + } + } +} + +fn expand_auto_deserialize( + cx: ext_ctxt, + span: span, + _mitem: ast::meta_item, + in_items: ~[@ast::item] +) -> ~[@ast::item] { + fn is_auto_deserialize(a: &ast::attribute) -> bool { + attr::get_attr_name(*a) == ~"auto_deserialize" + } + + fn filter_attrs(item: @ast::item) -> @ast::item { + @{attrs: vec::filter(item.attrs, |a| !is_auto_deserialize(a)), + .. *item} + } + + do vec::flat_map(in_items) |item| { + if item.attrs.any(is_auto_deserialize) { + match item.node { + ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => { + let deser_impl = mk_rec_deser_impl( + cx, + item.span, + item.ident, + fields, + tps + ); + + ~[filter_attrs(*item), deser_impl] + }, + ast::item_class(@{ fields, _}, tps) => { + let deser_impl = mk_struct_deser_impl( + cx, + item.span, + item.ident, + fields, + tps + ); + + ~[filter_attrs(*item), deser_impl] + }, + ast::item_enum(enum_def, tps) => { + let deser_impl = mk_enum_deser_impl( + cx, + item.span, + item.ident, + enum_def, + tps + ); + + ~[filter_attrs(*item), deser_impl] + }, + _ => { + cx.span_err(span, ~"#[auto_deserialize] can only be \ + applied to structs, record types, \ + and enum definitions"); + ~[*item] + } + } + } else { + ~[*item] } } } priv impl ext_ctxt { - fn helper_path(base_path: @ast::path, - helper_name: ~str) -> @ast::path { - let head = vec::init(base_path.idents); - let tail = vec::last(base_path.idents); - self.path(base_path.span, - vec::append(head, - ~[self.parse_sess().interner. - intern(@(helper_name + ~"_" + - *self.parse_sess().interner.get( - tail)))])) + fn expr(span: span, node: ast::expr_) -> @ast::expr { + @{id: self.next_id(), callee_id: self.next_id(), + node: node, span: span} } - fn ty_fn(span: span, - -input_tys: ~[@ast::ty], - -output: @ast::ty) -> @ast::ty { - let args = do vec::map(input_tys) |ty| { - {mode: ast::expl(ast::by_ref), - ty: *ty, - ident: parse::token::special_idents::invalid, - id: self.next_id()} - }; + fn path(span: span, strs: ~[ast::ident]) -> @ast::path { + @{span: span, global: false, idents: strs, rp: None, types: ~[]} + } + fn path_tps(span: span, strs: ~[ast::ident], + tps: ~[@ast::ty]) -> @ast::path { + @{span: span, global: false, idents: strs, rp: None, types: tps} + } + + fn ty_path(span: span, strs: ~[ast::ident], + tps: ~[@ast::ty]) -> @ast::ty { @{id: self.next_id(), - node: ast::ty_fn(ast::proto_block, - ast::impure_fn, - @~[], - {inputs: args, - output: output, - cf: ast::return_val}), + node: ast::ty_path(self.path_tps(span, strs, tps), self.next_id()), span: span} } - fn ty_nil(span: span) -> @ast::ty { - @{id: self.next_id(), node: ast::ty_nil, span: span} + fn binder_pat(span: span, nm: ast::ident) -> @ast::pat { + let path = @{span: span, global: false, idents: ~[nm], + rp: None, types: ~[]}; + @{id: self.next_id(), + node: ast::pat_ident(ast::bind_by_implicit_ref, + path, + None), + span: span} } - fn var_ref(span: span, name: ast::ident) -> @ast::expr { - self.expr(span, ast::expr_path(self.path(span, ~[name]))) + fn stmt(expr: @ast::expr) -> @ast::stmt { + @{node: ast::stmt_semi(expr, self.next_id()), + span: expr.span} } - fn alt_stmt(arms: ~[ast::arm], - span: span, -v: @ast::expr) -> @ast::stmt { - self.stmt( - self.expr( - span, - ast::expr_match(v, arms))) + fn lit_str(span: span, s: @~str) -> @ast::expr { + self.expr( + span, + ast::expr_vstore( + self.expr( + span, + ast::expr_lit( + @{node: ast::lit_str(s), + span: span})), + ast::expr_vstore_uniq)) } - fn clone_folder() -> fold::ast_fold { - fold::make_fold(@{ - new_id: |_id| self.next_id(), - .. *fold::default_ast_fold() - }) + fn lit_uint(span: span, i: uint) -> @ast::expr { + self.expr( + span, + ast::expr_lit( + @{node: ast::lit_uint(i as u64, ast::ty_u), + span: span})) } - fn clone(v: @ast::expr) -> @ast::expr { - let fld = self.clone_folder(); - fld.fold_expr(v) + fn lambda(blk: ast::blk) -> @ast::expr { + let ext_cx = self; + let blk_e = self.expr(blk.span, ast::expr_block(blk)); + #ast{ || $(blk_e) } } - fn clone_ty(v: @ast::ty) -> @ast::ty { - let fld = self.clone_folder(); - fld.fold_ty(v) + fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk { + {node: {view_items: ~[], + stmts: stmts, + expr: None, + id: self.next_id(), + rules: ast::default_blk}, + span: span} } - fn clone_ty_param(v: ast::ty_param) -> ast::ty_param { - let fld = self.clone_folder(); - fold::fold_ty_param(v, fld) + fn expr_blk(expr: @ast::expr) -> ast::blk { + {node: {view_items: ~[], + stmts: ~[], + expr: Some(expr), + id: self.next_id(), + rules: ast::default_blk}, + span: expr.span} } - fn at(span: span, expr: @ast::expr) -> @ast::expr { - fn repl_sp(old_span: span, repl_span: span, with_span: span) -> span { - if old_span == repl_span { - with_span - } else { - old_span - } - } + fn expr_path(span: span, strs: ~[ast::ident]) -> @ast::expr { + self.expr(span, ast::expr_path(self.path(span, strs))) + } - let fld = fold::make_fold(@{ - new_span: |a| repl_sp(a, ast_util::dummy_sp(), span), - .. *fold::default_ast_fold() + fn expr_var(span: span, var: ~str) -> @ast::expr { + self.expr_path(span, ~[self.ident_of(var)]) + } + + fn expr_field( + span: span, + expr: @ast::expr, + ident: ast::ident + ) -> @ast::expr { + self.expr(span, ast::expr_field(expr, ident, ~[])) + } + + fn expr_call( + span: span, + expr: @ast::expr, + args: ~[@ast::expr] + ) -> @ast::expr { + self.expr(span, ast::expr_call(expr, args, false)) + } + + fn lambda_expr(expr: @ast::expr) -> @ast::expr { + self.lambda(self.expr_blk(expr)) + } + + fn lambda_stmts(span: span, stmts: ~[@ast::stmt]) -> @ast::expr { + self.lambda(self.blk(span, stmts)) + } +} + +fn mk_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + path: @ast::path, + tps: ~[ast::ty_param], + f: fn(@ast::ty) -> @ast::method +) -> @ast::item { + // All the type parameters need to bound to the trait. + let trait_tps = do tps.map |tp| { + let t_bound = ast::bound_trait(@{ + id: cx.next_id(), + node: ast::ty_path(path, cx.next_id()), + span: span, }); - fld.fold_expr(expr) - } -} - -fn ser_path(cx: ext_ctxt, tps: ser_tps_map, path: @ast::path, - -s: @ast::expr, -v: @ast::expr) - -> ~[@ast::stmt] { - let ext_cx = cx; // required for #ast{} - - // We want to take a path like a::b::c<...> and generate a call - // like a::b::c::serialize(s, ...), as described above. - - let callee = - cx.expr( - path.span, - ast::expr_path( - cx.helper_path(path, ~"serialize"))); - - let ty_args = do vec::map(path.types) |ty| { - let sv_stmts = ser_ty(cx, tps, *ty, cx.clone(s), #ast{ __v }); - let sv = cx.expr(path.span, - ast::expr_block(cx.blk(path.span, sv_stmts))); - cx.at(ty.span, #ast{ |__v| $(sv) }) - }; - - ~[cx.stmt( - cx.expr( - path.span, - ast::expr_call(callee, vec::append(~[s, v], ty_args), false)))] -} - -fn ser_variant(cx: ext_ctxt, - tps: ser_tps_map, - tys: ~[@ast::ty], - span: span, - -s: @ast::expr, - pfn: fn(~[@ast::pat]) -> ast::pat_, - bodyfn: fn(-v: @ast::expr, ast::blk) -> @ast::expr, - argfn: fn(-v: @ast::expr, uint, ast::blk) -> @ast::expr) - -> ast::arm { - let vnames = do vec::from_fn(vec::len(tys)) |i| { - cx.parse_sess().interner.intern(@fmt!("__v%u", i)) - }; - let pats = do vec::from_fn(vec::len(tys)) |i| { - cx.binder_pat(tys[i].span, vnames[i]) - }; - let pat: @ast::pat = @{id: cx.next_id(), node: pfn(pats), span: span}; - let stmts = do vec::from_fn(vec::len(tys)) |i| { - let v = cx.var_ref(span, vnames[i]); - let arg_blk = - cx.blk( - span, - ser_ty(cx, tps, tys[i], cx.clone(s), move v)); - cx.stmt(argfn(cx.clone(s), i, arg_blk)) - }; - - let body_blk = cx.blk(span, stmts); - let body = cx.blk(span, ~[cx.stmt(bodyfn(move s, body_blk))]); - - {pats: ~[pat], guard: None, body: body} -} - -fn ser_lambda(cx: ext_ctxt, tps: ser_tps_map, ty: @ast::ty, - -s: @ast::expr, -v: @ast::expr) -> @ast::expr { - cx.lambda(cx.blk(ty.span, ser_ty(cx, tps, ty, move s, move v))) -} - -fn is_vec_or_str(ty: @ast::ty) -> bool { - match ty.node { - ast::ty_vec(_) => true, - // This may be wrong if the user has shadowed (!) str - ast::ty_path(@{span: _, global: _, idents: ids, - rp: None, types: _}, _) - if ids == ~[parse::token::special_idents::str] => true, - _ => false - } -} - -fn ser_ty(cx: ext_ctxt, tps: ser_tps_map, - ty: @ast::ty, -s: @ast::expr, -v: @ast::expr) - -> ~[@ast::stmt] { - - let ext_cx = cx; // required for #ast{} - - match ty.node { - ast::ty_nil => { - ~[#ast[stmt]{$(s).emit_nil()}] - } - - ast::ty_bot => { - cx.span_err( - ty.span, fmt!("Cannot serialize bottom type")); - ~[] - } - - ast::ty_box(mt) => { - let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) }); - ~[#ast[stmt]{$(s).emit_box($(l));}] - } - - // For unique evecs/estrs, just pass through to underlying vec or str - ast::ty_uniq(mt) if is_vec_or_str(mt.ty) => { - ser_ty(cx, tps, mt.ty, move s, move v) - } - - ast::ty_uniq(mt) => { - let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) }); - ~[#ast[stmt]{$(s).emit_uniq($(l));}] - } - - ast::ty_ptr(_) | ast::ty_rptr(_, _) => { - cx.span_err(ty.span, ~"cannot serialize pointer types"); - ~[] - } - - ast::ty_rec(flds) => { - let fld_stmts = do vec::from_fn(vec::len(flds)) |fidx| { - let fld = flds[fidx]; - let vf = cx.expr(fld.span, - ast::expr_field(cx.clone(v), - fld.node.ident, - ~[])); - let s = cx.clone(s); - let f = cx.lit_str(fld.span, cx.parse_sess().interner.get( - fld.node.ident)); - let i = cx.lit_uint(fld.span, fidx); - let l = ser_lambda(cx, tps, fld.node.mt.ty, cx.clone(s), move vf); - #ast[stmt]{$(s).emit_rec_field($(f), $(i), $(l));} - }; - let fld_lambda = cx.lambda(cx.blk(ty.span, fld_stmts)); - ~[#ast[stmt]{$(s).emit_rec($(fld_lambda));}] - } - - ast::ty_fn(*) => { - cx.span_err(ty.span, ~"cannot serialize function types"); - ~[] - } - - ast::ty_tup(tys) => { - // Generate code like - // - // match v { - // (v1, v2, v3) { - // .. serialize v1, v2, v3 .. - // } - // }; - - let arms = ~[ - ser_variant( - - cx, tps, tys, ty.span, move s, - - // Generate pattern (v1, v2, v3) - |pats| ast::pat_tup(pats), - - // Generate body s.emit_tup(3, {|| blk }) - |-s, blk| { - let sz = cx.lit_uint(ty.span, vec::len(tys)); - let body = cx.lambda(blk); - #ast{ $(s).emit_tup($(sz), $(body)) } - }, - - // Generate s.emit_tup_elt(i, {|| blk }) - |-s, i, blk| { - let idx = cx.lit_uint(ty.span, i); - let body = cx.lambda(blk); - #ast{ $(s).emit_tup_elt($(idx), $(body)) } - }) - ]; - ~[cx.alt_stmt(arms, ty.span, move v)] - } - - ast::ty_path(path, _) => { - if path.idents.len() == 1 && path.types.is_empty() { - let ident = path.idents[0]; - - match tps.find(ident) { - Some(f) => f(v), - None => ser_path(cx, tps, path, move s, move v) - } - } else { - ser_path(cx, tps, path, move s, move v) + { + ident: tp.ident, + id: cx.next_id(), + bounds: @vec::append(~[t_bound], *tp.bounds) } - } - - ast::ty_mac(_) => { - cx.span_err(ty.span, ~"cannot serialize macro types"); - ~[] - } - - ast::ty_infer => { - cx.span_err(ty.span, ~"cannot serialize inferred types"); - ~[] - } - - ast::ty_vec(mt) => { - let ser_e = - cx.expr( - ty.span, - ast::expr_block( - cx.blk( - ty.span, - ser_ty( - cx, tps, mt.ty, - cx.clone(s), - cx.at(ty.span, #ast{ __e }))))); - - ~[#ast[stmt]{ - std::serialization::emit_from_vec($(s), $(v), |__e| $(ser_e)) - }] - } - - ast::ty_fixed_length(_, _) => { - cx.span_unimpl(ty.span, ~"serialization for fixed length types"); - } - } -} - -fn mk_ser_fn(cx: ext_ctxt, span: span, name: ast::ident, - tps: ~[ast::ty_param], - f: fn(ext_ctxt, ser_tps_map, - -v: @ast::expr, -v: @ast::expr) -> ~[@ast::stmt]) - -> @ast::item { - let ext_cx = cx; // required for #ast - - let tp_types = vec::map(tps, |tp| cx.ty_path(span, ~[tp.ident], ~[])); - let v_ty = cx.ty_path(span, ~[name], tp_types); - - let tp_inputs = - vec::map(tps, |tp| - {mode: ast::expl(ast::by_ref), - ty: cx.ty_fn(span, - ~[cx.ty_path(span, ~[tp.ident], ~[])], - cx.ty_nil(span)), - ident: cx.ident_of(~"__s" + cx.str_of(tp.ident)), - id: cx.next_id()}); - - debug!("tp_inputs = %?", tp_inputs); - - - let ser_inputs: ~[ast::arg] = - vec::append(~[{mode: ast::expl(ast::by_ref), - ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), - ident: cx.ident_of(~"__s"), - id: cx.next_id()}, - {mode: ast::expl(ast::by_ref), - ty: v_ty, - ident: cx.ident_of(~"__v"), - id: cx.next_id()}], - tp_inputs); - - let tps_map = map::HashMap(); - for vec::each2(tps, tp_inputs) |tp, arg| { - let arg_ident = arg.ident; - tps_map.insert( - tp.ident, - fn@(v: @ast::expr) -> ~[@ast::stmt] { - let f = cx.var_ref(span, arg_ident); - debug!("serializing type arg %s", cx.str_of(arg_ident)); - ~[#ast[stmt]{$(f)($(v));}] - }); - } - - let ser_bnds = @~[ - ast::bound_trait(cx.ty_path(span, - ~[cx.ident_of(~"std"), - cx.ident_of(~"serialization"), - cx.ident_of(~"Serializer")], - ~[]))]; - - let ser_tps: ~[ast::ty_param] = - vec::append(~[{ident: cx.ident_of(~"__S"), - id: cx.next_id(), - bounds: ser_bnds}], - vec::map(tps, |tp| cx.clone_ty_param(*tp))); - - let ser_output: @ast::ty = @{id: cx.next_id(), - node: ast::ty_nil, - span: span}; - - let ser_blk = cx.blk(span, - f(cx, tps_map, #ast{ __s }, #ast{ __v })); - - @{ident: cx.ident_of(~"serialize_" + cx.str_of(name)), - attrs: ~[], - id: cx.next_id(), - node: ast::item_fn({inputs: ser_inputs, - output: ser_output, - cf: ast::return_val}, - ast::impure_fn, - ser_tps, - ser_blk), - vis: ast::public, - span: span} -} - -// ______________________________________________________________________ - -fn deser_path(cx: ext_ctxt, tps: deser_tps_map, path: @ast::path, - -d: @ast::expr) -> @ast::expr { - // We want to take a path like a::b::c<...> and generate a call - // like a::b::c::deserialize(d, ...), as described above. - - let callee = - cx.expr( - path.span, - ast::expr_path( - cx.helper_path(path, ~"deserialize"))); - - let ty_args = do vec::map(path.types) |ty| { - let dv_expr = deser_ty(cx, tps, *ty, cx.clone(d)); - cx.lambda(cx.expr_blk(dv_expr)) }; - cx.expr(path.span, ast::expr_call(callee, vec::append(~[d], ty_args), - false)) + let opt_trait = Some(@{ + path: path, + ref_id: cx.next_id(), + impl_id: cx.next_id(), + }); + + let ty = cx.ty_path( + span, + ~[ident], + tps.map(|tp| cx.ty_path(span, ~[tp.ident], ~[])) + ); + + @{ + // This is a new-style impl declaration. + // XXX: clownshoes + ident: ast::token::special_idents::clownshoes_extensions, + attrs: ~[], + id: cx.next_id(), + node: ast::item_impl(trait_tps, opt_trait, ty, ~[f(ty)]), + vis: ast::public, + span: span, + } } -fn deser_lambda(cx: ext_ctxt, tps: deser_tps_map, ty: @ast::ty, - -d: @ast::expr) -> @ast::expr { - cx.lambda(cx.expr_blk(deser_ty(cx, tps, ty, move d))) +fn mk_ser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + tps: ~[ast::ty_param], + body: @ast::expr +) -> @ast::item { + // Make a path to the std::serialization::Serializable trait. + let path = cx.path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"Serializable"), + ] + ); + + mk_impl( + cx, + span, + ident, + path, + tps, + |_ty| mk_ser_method(cx, span, cx.expr_blk(body)) + ) } -fn deser_ty(cx: ext_ctxt, tps: deser_tps_map, - ty: @ast::ty, -d: @ast::expr) -> @ast::expr { +fn mk_deser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + tps: ~[ast::ty_param], + body: @ast::expr +) -> @ast::item { + // Make a path to the std::serialization::Deserializable trait. + let path = cx.path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"Deserializable"), + ] + ); - let ext_cx = cx; // required for #ast{} + mk_impl( + cx, + span, + ident, + path, + tps, + |ty| mk_deser_method(cx, span, ty, cx.expr_blk(body)) + ) +} - match ty.node { - ast::ty_nil => { - #ast{ $(d).read_nil() } - } +fn mk_ser_method( + cx: ext_ctxt, + span: span, + ser_body: ast::blk +) -> @ast::method { + let ser_bound = cx.ty_path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"Serializer"), + ], + ~[] + ); - ast::ty_bot => { - #ast{ fail } - } + let ser_tps = ~[{ + ident: cx.ident_of(~"__S"), + id: cx.next_id(), + bounds: @~[ast::bound_trait(ser_bound)], + }]; - ast::ty_box(mt) => { - let l = deser_lambda(cx, tps, mt.ty, cx.clone(d)); - #ast{ @$(d).read_box($(l)) } - } - - // For unique evecs/estrs, just pass through to underlying vec or str - ast::ty_uniq(mt) if is_vec_or_str(mt.ty) => { - deser_ty(cx, tps, mt.ty, move d) - } - - ast::ty_uniq(mt) => { - let l = deser_lambda(cx, tps, mt.ty, cx.clone(d)); - #ast{ ~$(d).read_uniq($(l)) } - } - - ast::ty_ptr(_) | ast::ty_rptr(_, _) => { - #ast{ fail } - } - - ast::ty_rec(flds) => { - let fields = do vec::from_fn(vec::len(flds)) |fidx| { - let fld = flds[fidx]; - let d = cx.clone(d); - let f = cx.lit_str(fld.span, @cx.str_of(fld.node.ident)); - let i = cx.lit_uint(fld.span, fidx); - let l = deser_lambda(cx, tps, fld.node.mt.ty, cx.clone(d)); - {node: {mutbl: fld.node.mt.mutbl, - ident: fld.node.ident, - expr: #ast{ $(d).read_rec_field($(f), $(i), $(l))} }, - span: fld.span} - }; - let fld_expr = cx.expr(ty.span, ast::expr_rec(fields, None)); - let fld_lambda = cx.lambda(cx.expr_blk(fld_expr)); - #ast{ $(d).read_rec($(fld_lambda)) } - } - - ast::ty_fn(*) => { - #ast{ fail } - } - - ast::ty_tup(tys) => { - // Generate code like - // - // d.read_tup(3u) {|| - // (d.read_tup_elt(0u, {||...}), - // d.read_tup_elt(1u, {||...}), - // d.read_tup_elt(2u, {||...})) - // } - - let arg_exprs = do vec::from_fn(vec::len(tys)) |i| { - let idx = cx.lit_uint(ty.span, i); - let body = deser_lambda(cx, tps, tys[i], cx.clone(d)); - #ast{ $(d).read_tup_elt($(idx), $(body)) } - }; - let body = - cx.lambda(cx.expr_blk( - cx.expr(ty.span, ast::expr_tup(arg_exprs)))); - let sz = cx.lit_uint(ty.span, vec::len(tys)); - #ast{ $(d).read_tup($(sz), $(body)) } - } - - ast::ty_path(path, _) => { - if vec::len(path.idents) == 1u && - vec::is_empty(path.types) { - let ident = path.idents[0]; - - match tps.find(ident) { - Some(f) => f(), - None => deser_path(cx, tps, path, move d) + let ty_s = @{ + id: cx.next_id(), + node: ast::ty_rptr( + @{ + id: cx.next_id(), + node: ast::re_anon, + }, + { + ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), + mutbl: ast::m_imm } - } else { - deser_path(cx, tps, path, move d) - } - } + ), + span: span, + }; - ast::ty_mac(_) => { - #ast{ fail } - } + let ser_inputs = ~[{ + mode: ast::infer(cx.next_id()), + ty: ty_s, + ident: cx.ident_of(~"__s"), + id: cx.next_id(), + }]; - ast::ty_infer => { - #ast{ fail } - } + let ser_output = @{ + id: cx.next_id(), + node: ast::ty_nil, + span: span, + }; - ast::ty_vec(mt) => { - let l = deser_lambda(cx, tps, mt.ty, cx.clone(d)); - #ast{ std::serialization::read_to_vec($(d), $(l)) } - } + let ser_decl = { + inputs: ser_inputs, + output: ser_output, + cf: ast::return_val, + }; - ast::ty_fixed_length(_, _) => { - cx.span_unimpl(ty.span, ~"deserialization for fixed length types"); - } + @{ + ident: cx.ident_of(~"serialize"), + attrs: ~[], + tps: ser_tps, + self_ty: { node: ast::sty_region(ast::m_imm), span: span }, + purity: ast::impure_fn, + decl: ser_decl, + body: ser_body, + id: cx.next_id(), + span: span, + self_id: cx.next_id(), + vis: ast::public, } } -fn mk_deser_fn(cx: ext_ctxt, span: span, - name: ast::ident, tps: ~[ast::ty_param], - f: fn(ext_ctxt, deser_tps_map, -v: @ast::expr) -> @ast::expr) - -> @ast::item { - let ext_cx = cx; // required for #ast +fn mk_deser_method( + cx: ext_ctxt, + span: span, + ty: @ast::ty, + deser_body: ast::blk +) -> @ast::method { + let deser_bound = cx.ty_path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"Deserializer"), + ], + ~[] + ); - let tp_types = vec::map(tps, |tp| cx.ty_path(span, ~[tp.ident], ~[])); - let v_ty = cx.ty_path(span, ~[name], tp_types); + let deser_tps = ~[{ + ident: cx.ident_of(~"__D"), + id: cx.next_id(), + bounds: @~[ast::bound_trait(deser_bound)], + }]; - let tp_inputs = - vec::map(tps, |tp| - {mode: ast::expl(ast::by_ref), - ty: cx.ty_fn(span, - ~[], - cx.ty_path(span, ~[tp.ident], ~[])), - ident: cx.ident_of(~"__d" + cx.str_of(tp.ident)), - id: cx.next_id()}); + let ty_d = @{ + id: cx.next_id(), + node: ast::ty_rptr( + @{ + id: cx.next_id(), + node: ast::re_anon, + }, + { + ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), + mutbl: ast::m_imm + } + ), + span: span, + }; - debug!("tp_inputs = %?", tp_inputs); + let deser_inputs = ~[{ + mode: ast::infer(cx.next_id()), + ty: ty_d, + ident: cx.ident_of(~"__d"), + id: cx.next_id(), + }]; - let deser_inputs: ~[ast::arg] = - vec::append(~[{mode: ast::expl(ast::by_ref), - ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), - ident: cx.ident_of(~"__d"), - id: cx.next_id()}], - tp_inputs); + let deser_decl = { + inputs: deser_inputs, + output: ty, + cf: ast::return_val, + }; - let tps_map = map::HashMap(); - for vec::each2(tps, tp_inputs) |tp, arg| { - let arg_ident = arg.ident; - tps_map.insert( - tp.ident, - fn@() -> @ast::expr { - let f = cx.var_ref(span, arg_ident); - #ast{ $(f)() } - }); + @{ + ident: cx.ident_of(~"deserialize"), + attrs: ~[], + tps: deser_tps, + self_ty: { node: ast::sty_static, span: span }, + purity: ast::impure_fn, + decl: deser_decl, + body: deser_body, + id: cx.next_id(), + span: span, + self_id: cx.next_id(), + vis: ast::public, } +} - let deser_bnds = @~[ - ast::bound_trait(cx.ty_path( +fn mk_rec_ser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + fields: ~[ast::ty_field], + tps: ~[ast::ty_param] +) -> @ast::item { + let fields = mk_ser_fields(cx, span, mk_rec_fields(fields)); + + // ast for `__s.emit_rec(|| $(fields))` + let body = cx.expr_call( + span, + cx.expr_field( span, - ~[cx.ident_of(~"std"), cx.ident_of(~"serialization"), - cx.ident_of(~"Deserializer")], - ~[]))]; + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_rec") + ), + ~[cx.lambda_stmts(span, fields)] + ); - let deser_tps: ~[ast::ty_param] = - vec::append(~[{ident: cx.ident_of(~"__D"), - id: cx.next_id(), - bounds: deser_bnds}], - vec::map(tps, |tp| { - let cloned = cx.clone_ty_param(*tp); - {bounds: @(vec::append(*cloned.bounds, - ~[ast::bound_copy])), - .. cloned} - })); - - let deser_blk = cx.expr_blk(f(cx, tps_map, #ast[expr]{__d})); - - @{ident: cx.ident_of(~"deserialize_" + cx.str_of(name)), - attrs: ~[], - id: cx.next_id(), - node: ast::item_fn({inputs: deser_inputs, - output: v_ty, - cf: ast::return_val}, - ast::impure_fn, - deser_tps, - deser_blk), - vis: ast::public, - span: span} + mk_ser_impl(cx, span, ident, tps, body) } -fn ty_fns(cx: ext_ctxt, name: ast::ident, - ty: @ast::ty, tps: ~[ast::ty_param]) - -> ~[@ast::item] { +fn mk_rec_deser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + fields: ~[ast::ty_field], + tps: ~[ast::ty_param] +) -> @ast::item { + let fields = mk_deser_fields(cx, span, mk_rec_fields(fields)); - let span = ty.span; - ~[ - mk_ser_fn(cx, span, name, tps, |a,b,c,d| ser_ty(a, b, ty, move c, - move d)), - mk_deser_fn(cx, span, name, tps, |a,b,c| deser_ty(a, b, ty, move c)) - ] + // ast for `read_rec(|| $(fields))` + let body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_rec") + ), + ~[ + cx.lambda_expr( + cx.expr( + span, + ast::expr_rec(fields, None) + ) + ) + ] + ); + + mk_deser_impl(cx, span, ident, tps, body) } -fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: ast::ident, - e_span: span, variants: ~[ast::variant], - -s: @ast::expr, -v: @ast::expr) -> ~[@ast::stmt] { - let ext_cx = cx; - let arms = do vec::from_fn(vec::len(variants)) |vidx| { - let variant = variants[vidx]; - let v_span = variant.span; - let v_name = variant.node.name; +fn mk_struct_ser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + fields: ~[@ast::struct_field], + tps: ~[ast::ty_param] +) -> @ast::item { + let fields = mk_ser_fields(cx, span, mk_struct_fields(fields)); - match variant.node.kind { - ast::tuple_variant_kind(args) => { - let variant_tys = vec::map(args, |a| a.ty); + // ast for `__s.emit_struct($(name), || $(fields))` + let ser_body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_struct") + ), + ~[ + cx.lit_str(span, @cx.str_of(ident)), + cx.lambda_stmts(span, fields), + ] + ); - ser_variant( - cx, tps, variant_tys, v_span, cx.clone(s), + mk_ser_impl(cx, span, ident, tps, ser_body) +} - // Generate pattern var(v1, v2, v3) - |pats| { - if vec::is_empty(pats) { - ast::pat_ident(ast::bind_by_implicit_ref, - cx.path(v_span, ~[v_name]), - None) - } else { - ast::pat_enum(cx.path(v_span, ~[v_name]), - Some(pats)) - } - }, +fn mk_struct_deser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + fields: ~[@ast::struct_field], + tps: ~[ast::ty_param] +) -> @ast::item { + let fields = mk_deser_fields(cx, span, mk_struct_fields(fields)); - // Generate body s.emit_enum_variant("foo", 0u, - // 3u, {|| blk }) - |-s, blk| { - let v_name = cx.lit_str(v_span, @cx.str_of(v_name)); - let v_id = cx.lit_uint(v_span, vidx); - let sz = cx.lit_uint(v_span, vec::len(variant_tys)); - let body = cx.lambda(blk); - #ast[expr]{ - $(s).emit_enum_variant($(v_name), $(v_id), - $(sz), $(body)) - } - }, + // ast for `read_struct($(name), || $(fields))` + let body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_struct") + ), + ~[ + cx.lit_str(span, @cx.str_of(ident)), + cx.lambda_expr( + cx.expr( + span, + ast::expr_struct( + cx.path(span, ~[ident]), + fields, + None + ) + ) + ), + ] + ); - // Generate s.emit_enum_variant_arg(i, {|| blk }) - |-s, i, blk| { - let idx = cx.lit_uint(v_span, i); - let body = cx.lambda(blk); - #ast[expr]{ - $(s).emit_enum_variant_arg($(idx), $(body)) - } - }) - } - _ => - fail ~"struct variants unimplemented for auto serialize" + mk_deser_impl(cx, span, ident, tps, body) +} + +// Records and structs don't have the same fields types, but they share enough +// that if we extract the right subfields out we can share the serialization +// generator code. +type field = { span: span, ident: ast::ident, mutbl: ast::mutability }; + +fn mk_rec_fields(fields: ~[ast::ty_field]) -> ~[field] { + do fields.map |field| { + { + span: field.span, + ident: field.node.ident, + mutbl: field.node.mt.mutbl, } - }; - let lam = cx.lambda(cx.blk(e_span, ~[cx.alt_stmt(arms, e_span, move v)])); - let e_name = cx.lit_str(e_span, @cx.str_of(e_name)); - ~[#ast[stmt]{ $(s).emit_enum($(e_name), $(lam)) }] + } } -fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident, - e_span: span, variants: ~[ast::variant], - -d: @ast::expr) -> @ast::expr { - let ext_cx = cx; - let mut arms: ~[ast::arm] = do vec::from_fn(vec::len(variants)) |vidx| { - let variant = variants[vidx]; - let v_span = variant.span; - let v_name = variant.node.name; +fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] { + do fields.map |field| { + let (ident, mutbl) = match field.node.kind { + ast::named_field(ident, mutbl, _) => (ident, mutbl), + _ => fail ~"[auto_serialize] does not support \ + unnamed fields", + }; - let body; + { + span: field.span, + ident: ident, + mutbl: match mutbl { + ast::class_mutable => ast::m_mutbl, + ast::class_immutable => ast::m_imm, + }, + } + } +} + +fn mk_ser_fields( + cx: ext_ctxt, + span: span, + fields: ~[field] +) -> ~[@ast::stmt] { + do fields.mapi |idx, field| { + // ast for `|| self.$(name).serialize(__s)` + let expr_lambda = cx.lambda_expr( + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"self"), + field.ident + ), + cx.ident_of(~"serialize") + ), + ~[cx.expr_var(span, ~"__s")] + ) + ); + + // ast for `__s.emit_field($(name), $(idx), $(expr_lambda))` + cx.stmt( + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_field") + ), + ~[ + cx.lit_str(span, @cx.str_of(field.ident)), + cx.lit_uint(span, idx), + expr_lambda, + ] + ) + ) + } +} + +fn mk_deser_fields( + cx: ext_ctxt, + span: span, + fields: ~[{ span: span, ident: ast::ident, mutbl: ast::mutability }] +) -> ~[ast::field] { + do fields.mapi |idx, field| { + // ast for `|| std::serialization::deserialize(__d)` + let expr_lambda = cx.lambda( + cx.expr_blk( + cx.expr_call( + span, + cx.expr_path(span, ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"deserialize"), + ]), + ~[cx.expr_var(span, ~"__d")] + ) + ) + ); + + // ast for `__d.read_field($(name), $(idx), $(expr_lambda))` + let expr: @ast::expr = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_field") + ), + ~[ + cx.lit_str(span, @cx.str_of(field.ident)), + cx.lit_uint(span, idx), + expr_lambda, + ] + ); + + { + node: { mutbl: field.mutbl, ident: field.ident, expr: expr }, + span: span, + } + } +} + +fn mk_enum_ser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + enum_def: ast::enum_def, + tps: ~[ast::ty_param] +) -> @ast::item { + let body = mk_enum_ser_body( + cx, + span, + ident, + enum_def.variants + ); + + mk_ser_impl(cx, span, ident, tps, body) +} + +fn mk_enum_deser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + enum_def: ast::enum_def, + tps: ~[ast::ty_param] +) -> @ast::item { + let body = mk_enum_deser_body( + cx, + span, + ident, + enum_def.variants + ); + + mk_deser_impl(cx, span, ident, tps, body) +} + +fn ser_variant( + cx: ext_ctxt, + span: span, + v_name: ast::ident, + v_idx: uint, + args: ~[ast::variant_arg] +) -> ast::arm { + // Name the variant arguments. + let names = args.mapi(|i, _arg| cx.ident_of(fmt!("__v%u", i))); + + // Bind the names to the variant argument type. + let pats = args.mapi(|i, arg| cx.binder_pat(arg.ty.span, names[i])); + + let pat_node = if pats.is_empty() { + ast::pat_ident( + ast::bind_by_implicit_ref, + cx.path(span, ~[v_name]), + None + ) + } else { + ast::pat_enum( + cx.path(span, ~[v_name]), + Some(pats) + ) + }; + + let pat = @{ + id: cx.next_id(), + node: pat_node, + span: span, + }; + + let stmts = do args.mapi |a_idx, _arg| { + // ast for `__s.emit_enum_variant_arg` + let expr_emit = cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_enum_variant_arg") + ); + + // ast for `|| $(v).serialize(__s)` + let expr_serialize = cx.lambda_expr( + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_path(span, ~[names[a_idx]]), + cx.ident_of(~"serialize") + ), + ~[cx.expr_var(span, ~"__s")] + ) + ); + + // ast for `$(expr_emit)($(a_idx), $(expr_serialize))` + cx.stmt( + cx.expr_call( + span, + expr_emit, + ~[cx.lit_uint(span, a_idx), expr_serialize] + ) + ) + }; + + // ast for `__s.emit_enum_variant($(name), $(idx), $(sz), $(lambda))` + let body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_enum_variant") + ), + ~[ + cx.lit_str(span, @cx.str_of(v_name)), + cx.lit_uint(span, v_idx), + cx.lit_uint(span, stmts.len()), + cx.lambda_stmts(span, stmts), + ] + ); + + { pats: ~[pat], guard: None, body: cx.expr_blk(body) } +} + +fn mk_enum_ser_body( + cx: ext_ctxt, + span: span, + name: ast::ident, + variants: ~[ast::variant] +) -> @ast::expr { + let arms = do variants.mapi |v_idx, variant| { match variant.node.kind { - ast::tuple_variant_kind(args) => { - let tys = vec::map(args, |a| a.ty); - - let arg_exprs = do vec::from_fn(vec::len(tys)) |i| { - let idx = cx.lit_uint(v_span, i); - let body = deser_lambda(cx, tps, tys[i], cx.clone(d)); - #ast{ $(d).read_enum_variant_arg($(idx), $(body)) } - }; - - body = { - if vec::is_empty(tys) { - // for a nullary variant v, do "v" - cx.var_ref(v_span, v_name) - } else { - // for an n-ary variant v, do "v(a_1, ..., a_n)" - cx.expr(v_span, ast::expr_call( - cx.var_ref(v_span, v_name), arg_exprs, false)) - } - }; - } + ast::tuple_variant_kind(args) => + ser_variant(cx, span, variant.node.name, v_idx, args), ast::struct_variant_kind(*) => fail ~"struct variants unimplemented", ast::enum_variant_kind(*) => - fail ~"enum variants unimplemented" + fail ~"enum variants unimplemented", } - - {pats: ~[@{id: cx.next_id(), - node: ast::pat_lit(cx.lit_uint(v_span, vidx)), - span: v_span}], - guard: None, - body: cx.expr_blk(body)} }; - let impossible_case = {pats: ~[@{id: cx.next_id(), - node: ast::pat_wild, - span: e_span}], - guard: None, - // FIXME #3198: proper error message - body: cx.expr_blk(cx.expr(e_span, - ast::expr_fail(None)))}; - arms += ~[impossible_case]; + // ast for `match *self { $(arms) }` + let match_expr = cx.expr( + span, + ast::expr_match( + cx.expr( + span, + ast::expr_unary(ast::deref, cx.expr_var(span, ~"self")) + ), + arms + ) + ); - // Generate code like: - let e_name = cx.lit_str(e_span, @cx.str_of(e_name)); - let alt_expr = cx.expr(e_span, - ast::expr_match(#ast{__i}, arms)); - let var_lambda = #ast{ |__i| $(alt_expr) }; - let read_var = #ast{ $(cx.clone(d)).read_enum_variant($(var_lambda)) }; - let read_lambda = cx.lambda(cx.expr_blk(read_var)); - #ast{ $(d).read_enum($(e_name), $(read_lambda)) } + // ast for `__s.emit_enum($(name), || $(match_expr))` + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_enum") + ), + ~[ + cx.lit_str(span, @cx.str_of(name)), + cx.lambda_expr(match_expr), + ] + ) } -fn enum_fns(cx: ext_ctxt, e_name: ast::ident, e_span: span, - variants: ~[ast::variant], tps: ~[ast::ty_param]) - -> ~[@ast::item] { - ~[ - mk_ser_fn(cx, e_span, e_name, tps, - |a,b,c,d| ser_enum(a, b, e_name, e_span, variants, move c, - move d)), - mk_deser_fn(cx, e_span, e_name, tps, - |a,b,c| deser_enum(a, b, e_name, e_span, variants, move c)) - ] +fn mk_enum_deser_variant_nary( + cx: ext_ctxt, + span: span, + name: ast::ident, + args: ~[ast::variant_arg] +) -> @ast::expr { + let args = do args.mapi |idx, _arg| { + // ast for `|| std::serialization::deserialize(__d)` + let expr_lambda = cx.lambda_expr( + cx.expr_call( + span, + cx.expr_path(span, ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization"), + cx.ident_of(~"deserialize"), + ]), + ~[cx.expr_var(span, ~"__d")] + ) + ); + + // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))` + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_enum_variant_arg") + ), + ~[cx.lit_uint(span, idx), expr_lambda] + ) + }; + + // ast for `$(name)($(args))` + cx.expr_call(span, cx.expr_path(span, ~[name]), args) +} + +fn mk_enum_deser_body( + cx: ext_ctxt, + span: span, + name: ast::ident, + variants: ~[ast::variant] +) -> @ast::expr { + let mut arms = do variants.mapi |v_idx, variant| { + let body = match variant.node.kind { + ast::tuple_variant_kind(args) => { + if args.is_empty() { + // for a nullary variant v, do "v" + cx.expr_path(span, ~[variant.node.name]) + } else { + // for an n-ary variant v, do "v(a_1, ..., a_n)" + mk_enum_deser_variant_nary( + cx, + span, + variant.node.name, + args + ) + } + }, + ast::struct_variant_kind(*) => + fail ~"struct variants unimplemented", + ast::enum_variant_kind(*) => + fail ~"enum variants unimplemented", + }; + + let pat = @{ + id: cx.next_id(), + node: ast::pat_lit(cx.lit_uint(span, v_idx)), + span: span, + }; + + { + pats: ~[pat], + guard: None, + body: cx.expr_blk(body), + } + }; + + let impossible_case = { + pats: ~[@{ id: cx.next_id(), node: ast::pat_wild, span: span}], + guard: None, + + // FIXME(#3198): proper error message + body: cx.expr_blk(cx.expr(span, ast::expr_fail(None))), + }; + + arms.push(impossible_case); + + // ast for `|i| { match i { $(arms) } }` + let expr_lambda = cx.expr( + span, + ast::expr_fn_block( + { + inputs: ~[{ + mode: ast::infer(cx.next_id()), + ty: @{ + id: cx.next_id(), + node: ast::ty_infer, + span: span + }, + ident: cx.ident_of(~"i"), + id: cx.next_id(), + }], + output: @{ + id: cx.next_id(), + node: ast::ty_infer, + span: span, + }, + cf: ast::return_val, + }, + cx.expr_blk( + cx.expr( + span, + ast::expr_match(cx.expr_var(span, ~"i"), arms) + ) + ), + @~[] + ) + ); + + // ast for `__d.read_enum_variant($(expr_lambda))` + let expr_lambda = cx.lambda_expr( + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_enum_variant") + ), + ~[expr_lambda] + ) + ); + + // ast for `__d.read_enum($(e_name), $(expr_lambda))` + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_enum") + ), + ~[ + cx.lit_str(span, @cx.str_of(name)), + expr_lambda + ] + ) } diff --git a/src/libsyntax/ext/auto_serialize2.rs b/src/libsyntax/ext/auto_serialize2.rs deleted file mode 100644 index ba48b0d3f5f..00000000000 --- a/src/libsyntax/ext/auto_serialize2.rs +++ /dev/null @@ -1,1105 +0,0 @@ -/* - -The compiler code necessary to implement the #[auto_serialize2] and -#[auto_deserialize2] extension. The idea here is that type-defining items may -be tagged with #[auto_serialize2] and #[auto_deserialize2], which will cause -us to generate a little companion module with the same name as the item. - -For example, a type like: - - #[auto_serialize2] - #[auto_deserialize2] - struct Node {id: uint} - -would generate two implementations like: - - impl Node: Serializable { - fn serialize(s: &S) { - do s.emit_struct("Node") { - s.emit_field("id", 0, || s.emit_uint(self)) - } - } - } - - impl node_id: Deserializable { - static fn deserialize(d: &D) -> Node { - do d.read_struct("Node") { - Node { - id: d.read_field(~"x", 0, || deserialize(d)) - } - } - } - } - -Other interesting scenarios are whe the item has type parameters or -references other non-built-in types. A type definition like: - - #[auto_serialize2] - #[auto_deserialize2] - type spanned = {node: T, span: span}; - -would yield functions like: - - impl spanned: Serializable { - fn serialize(s: &S) { - do s.emit_rec { - s.emit_field("node", 0, || self.node.serialize(s)); - s.emit_field("span", 1, || self.span.serialize(s)); - } - } - } - - impl spanned: Deserializable { - static fn deserialize(d: &D) -> spanned { - do d.read_rec { - { - node: d.read_field(~"node", 0, || deserialize(d)), - span: d.read_field(~"span", 1, || deserialize(d)), - } - } - } - } - -FIXME (#2810)--Hygiene. Search for "__" strings. We also assume "std" is the -standard library. - -Misc notes: ------------ - -I use move mode arguments for ast nodes that will get inserted as is -into the tree. This is intended to prevent us from inserting the same -node twice. - -*/ - -use base::*; -use codemap::span; -use std::map; -use std::map::HashMap; - -export expand_auto_serialize; -export expand_auto_deserialize; - -// Transitional reexports so qquote can find the paths it is looking for -mod syntax { - pub use ext; - pub use parse; -} - -fn expand_auto_serialize( - cx: ext_ctxt, - span: span, - _mitem: ast::meta_item, - in_items: ~[@ast::item] -) -> ~[@ast::item] { - fn is_auto_serialize2(a: &ast::attribute) -> bool { - attr::get_attr_name(*a) == ~"auto_serialize2" - } - - fn filter_attrs(item: @ast::item) -> @ast::item { - @{attrs: vec::filter(item.attrs, |a| !is_auto_serialize2(a)), - .. *item} - } - - do vec::flat_map(in_items) |item| { - if item.attrs.any(is_auto_serialize2) { - match item.node { - ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => { - let ser_impl = mk_rec_ser_impl( - cx, - item.span, - item.ident, - fields, - tps - ); - - ~[filter_attrs(*item), ser_impl] - }, - ast::item_class(@{ fields, _}, tps) => { - let ser_impl = mk_struct_ser_impl( - cx, - item.span, - item.ident, - fields, - tps - ); - - ~[filter_attrs(*item), ser_impl] - }, - ast::item_enum(enum_def, tps) => { - let ser_impl = mk_enum_ser_impl( - cx, - item.span, - item.ident, - enum_def, - tps - ); - - ~[filter_attrs(*item), ser_impl] - }, - _ => { - cx.span_err(span, ~"#[auto_serialize2] can only be \ - applied to structs, record types, \ - and enum definitions"); - ~[*item] - } - } - } else { - ~[*item] - } - } -} - -fn expand_auto_deserialize( - cx: ext_ctxt, - span: span, - _mitem: ast::meta_item, - in_items: ~[@ast::item] -) -> ~[@ast::item] { - fn is_auto_deserialize2(a: &ast::attribute) -> bool { - attr::get_attr_name(*a) == ~"auto_deserialize2" - } - - fn filter_attrs(item: @ast::item) -> @ast::item { - @{attrs: vec::filter(item.attrs, |a| !is_auto_deserialize2(a)), - .. *item} - } - - do vec::flat_map(in_items) |item| { - if item.attrs.any(is_auto_deserialize2) { - match item.node { - ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => { - let deser_impl = mk_rec_deser_impl( - cx, - item.span, - item.ident, - fields, - tps - ); - - ~[filter_attrs(*item), deser_impl] - }, - ast::item_class(@{ fields, _}, tps) => { - let deser_impl = mk_struct_deser_impl( - cx, - item.span, - item.ident, - fields, - tps - ); - - ~[filter_attrs(*item), deser_impl] - }, - ast::item_enum(enum_def, tps) => { - let deser_impl = mk_enum_deser_impl( - cx, - item.span, - item.ident, - enum_def, - tps - ); - - ~[filter_attrs(*item), deser_impl] - }, - _ => { - cx.span_err(span, ~"#[auto_deserialize2] can only be \ - applied to structs, record types, \ - and enum definitions"); - ~[*item] - } - } - } else { - ~[*item] - } - } -} - -priv impl ext_ctxt { - fn expr(span: span, node: ast::expr_) -> @ast::expr { - @{id: self.next_id(), callee_id: self.next_id(), - node: node, span: span} - } - - fn path(span: span, strs: ~[ast::ident]) -> @ast::path { - @{span: span, global: false, idents: strs, rp: None, types: ~[]} - } - - fn path_tps(span: span, strs: ~[ast::ident], - tps: ~[@ast::ty]) -> @ast::path { - @{span: span, global: false, idents: strs, rp: None, types: tps} - } - - fn ty_path(span: span, strs: ~[ast::ident], - tps: ~[@ast::ty]) -> @ast::ty { - @{id: self.next_id(), - node: ast::ty_path(self.path_tps(span, strs, tps), self.next_id()), - span: span} - } - - fn binder_pat(span: span, nm: ast::ident) -> @ast::pat { - let path = @{span: span, global: false, idents: ~[nm], - rp: None, types: ~[]}; - @{id: self.next_id(), - node: ast::pat_ident(ast::bind_by_implicit_ref, - path, - None), - span: span} - } - - fn stmt(expr: @ast::expr) -> @ast::stmt { - @{node: ast::stmt_semi(expr, self.next_id()), - span: expr.span} - } - - fn lit_str(span: span, s: @~str) -> @ast::expr { - self.expr( - span, - ast::expr_vstore( - self.expr( - span, - ast::expr_lit( - @{node: ast::lit_str(s), - span: span})), - ast::expr_vstore_uniq)) - } - - fn lit_uint(span: span, i: uint) -> @ast::expr { - self.expr( - span, - ast::expr_lit( - @{node: ast::lit_uint(i as u64, ast::ty_u), - span: span})) - } - - fn lambda(blk: ast::blk) -> @ast::expr { - let ext_cx = self; - let blk_e = self.expr(blk.span, ast::expr_block(blk)); - #ast{ || $(blk_e) } - } - - fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk { - {node: {view_items: ~[], - stmts: stmts, - expr: None, - id: self.next_id(), - rules: ast::default_blk}, - span: span} - } - - fn expr_blk(expr: @ast::expr) -> ast::blk { - {node: {view_items: ~[], - stmts: ~[], - expr: Some(expr), - id: self.next_id(), - rules: ast::default_blk}, - span: expr.span} - } - - fn expr_path(span: span, strs: ~[ast::ident]) -> @ast::expr { - self.expr(span, ast::expr_path(self.path(span, strs))) - } - - fn expr_var(span: span, var: ~str) -> @ast::expr { - self.expr_path(span, ~[self.ident_of(var)]) - } - - fn expr_field( - span: span, - expr: @ast::expr, - ident: ast::ident - ) -> @ast::expr { - self.expr(span, ast::expr_field(expr, ident, ~[])) - } - - fn expr_call( - span: span, - expr: @ast::expr, - args: ~[@ast::expr] - ) -> @ast::expr { - self.expr(span, ast::expr_call(expr, args, false)) - } - - fn lambda_expr(expr: @ast::expr) -> @ast::expr { - self.lambda(self.expr_blk(expr)) - } - - fn lambda_stmts(span: span, stmts: ~[@ast::stmt]) -> @ast::expr { - self.lambda(self.blk(span, stmts)) - } -} - -fn mk_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - path: @ast::path, - tps: ~[ast::ty_param], - f: fn(@ast::ty) -> @ast::method -) -> @ast::item { - // All the type parameters need to bound to the trait. - let trait_tps = do tps.map |tp| { - let t_bound = ast::bound_trait(@{ - id: cx.next_id(), - node: ast::ty_path(path, cx.next_id()), - span: span, - }); - - { - ident: tp.ident, - id: cx.next_id(), - bounds: @vec::append(~[t_bound], *tp.bounds) - } - }; - - let opt_trait = Some(@{ - path: path, - ref_id: cx.next_id(), - impl_id: cx.next_id(), - }); - - let ty = cx.ty_path( - span, - ~[ident], - tps.map(|tp| cx.ty_path(span, ~[tp.ident], ~[])) - ); - - @{ - // This is a new-style impl declaration. - // XXX: clownshoes - ident: ast::token::special_idents::clownshoes_extensions, - attrs: ~[], - id: cx.next_id(), - node: ast::item_impl(trait_tps, opt_trait, ty, ~[f(ty)]), - vis: ast::public, - span: span, - } -} - -fn mk_ser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - tps: ~[ast::ty_param], - body: @ast::expr -) -> @ast::item { - // Make a path to the std::serialization2::Serializable trait. - let path = cx.path( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization2"), - cx.ident_of(~"Serializable"), - ] - ); - - mk_impl( - cx, - span, - ident, - path, - tps, - |_ty| mk_ser_method(cx, span, cx.expr_blk(body)) - ) -} - -fn mk_deser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - tps: ~[ast::ty_param], - body: @ast::expr -) -> @ast::item { - // Make a path to the std::serialization2::Deserializable trait. - let path = cx.path( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization2"), - cx.ident_of(~"Deserializable"), - ] - ); - - mk_impl( - cx, - span, - ident, - path, - tps, - |ty| mk_deser_method(cx, span, ty, cx.expr_blk(body)) - ) -} - -fn mk_ser_method( - cx: ext_ctxt, - span: span, - ser_body: ast::blk -) -> @ast::method { - let ser_bound = cx.ty_path( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization2"), - cx.ident_of(~"Serializer"), - ], - ~[] - ); - - let ser_tps = ~[{ - ident: cx.ident_of(~"__S"), - id: cx.next_id(), - bounds: @~[ast::bound_trait(ser_bound)], - }]; - - let ty_s = @{ - id: cx.next_id(), - node: ast::ty_rptr( - @{ - id: cx.next_id(), - node: ast::re_anon, - }, - { - ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), - mutbl: ast::m_imm - } - ), - span: span, - }; - - let ser_inputs = ~[{ - mode: ast::infer(cx.next_id()), - ty: ty_s, - ident: cx.ident_of(~"__s"), - id: cx.next_id(), - }]; - - let ser_output = @{ - id: cx.next_id(), - node: ast::ty_nil, - span: span, - }; - - let ser_decl = { - inputs: ser_inputs, - output: ser_output, - cf: ast::return_val, - }; - - @{ - ident: cx.ident_of(~"serialize"), - attrs: ~[], - tps: ser_tps, - self_ty: { node: ast::sty_region(ast::m_imm), span: span }, - purity: ast::impure_fn, - decl: ser_decl, - body: ser_body, - id: cx.next_id(), - span: span, - self_id: cx.next_id(), - vis: ast::public, - } -} - -fn mk_deser_method( - cx: ext_ctxt, - span: span, - ty: @ast::ty, - deser_body: ast::blk -) -> @ast::method { - let deser_bound = cx.ty_path( - span, - ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization2"), - cx.ident_of(~"Deserializer"), - ], - ~[] - ); - - let deser_tps = ~[{ - ident: cx.ident_of(~"__D"), - id: cx.next_id(), - bounds: @~[ast::bound_trait(deser_bound)], - }]; - - let ty_d = @{ - id: cx.next_id(), - node: ast::ty_rptr( - @{ - id: cx.next_id(), - node: ast::re_anon, - }, - { - ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), - mutbl: ast::m_imm - } - ), - span: span, - }; - - let deser_inputs = ~[{ - mode: ast::infer(cx.next_id()), - ty: ty_d, - ident: cx.ident_of(~"__d"), - id: cx.next_id(), - }]; - - let deser_decl = { - inputs: deser_inputs, - output: ty, - cf: ast::return_val, - }; - - @{ - ident: cx.ident_of(~"deserialize"), - attrs: ~[], - tps: deser_tps, - self_ty: { node: ast::sty_static, span: span }, - purity: ast::impure_fn, - decl: deser_decl, - body: deser_body, - id: cx.next_id(), - span: span, - self_id: cx.next_id(), - vis: ast::public, - } -} - -fn mk_rec_ser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - fields: ~[ast::ty_field], - tps: ~[ast::ty_param] -) -> @ast::item { - let fields = mk_ser_fields(cx, span, mk_rec_fields(fields)); - - // ast for `__s.emit_rec(|| $(fields))` - let body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_rec") - ), - ~[cx.lambda_stmts(span, fields)] - ); - - mk_ser_impl(cx, span, ident, tps, body) -} - -fn mk_rec_deser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - fields: ~[ast::ty_field], - tps: ~[ast::ty_param] -) -> @ast::item { - let fields = mk_deser_fields(cx, span, mk_rec_fields(fields)); - - // ast for `read_rec(|| $(fields))` - let body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_rec") - ), - ~[ - cx.lambda_expr( - cx.expr( - span, - ast::expr_rec(fields, None) - ) - ) - ] - ); - - mk_deser_impl(cx, span, ident, tps, body) -} - -fn mk_struct_ser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - fields: ~[@ast::struct_field], - tps: ~[ast::ty_param] -) -> @ast::item { - let fields = mk_ser_fields(cx, span, mk_struct_fields(fields)); - - // ast for `__s.emit_struct($(name), || $(fields))` - let ser_body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_struct") - ), - ~[ - cx.lit_str(span, @cx.str_of(ident)), - cx.lambda_stmts(span, fields), - ] - ); - - mk_ser_impl(cx, span, ident, tps, ser_body) -} - -fn mk_struct_deser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - fields: ~[@ast::struct_field], - tps: ~[ast::ty_param] -) -> @ast::item { - let fields = mk_deser_fields(cx, span, mk_struct_fields(fields)); - - // ast for `read_struct($(name), || $(fields))` - let body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_struct") - ), - ~[ - cx.lit_str(span, @cx.str_of(ident)), - cx.lambda_expr( - cx.expr( - span, - ast::expr_struct( - cx.path(span, ~[ident]), - fields, - None - ) - ) - ), - ] - ); - - mk_deser_impl(cx, span, ident, tps, body) -} - -// Records and structs don't have the same fields types, but they share enough -// that if we extract the right subfields out we can share the serialization -// generator code. -type field = { span: span, ident: ast::ident, mutbl: ast::mutability }; - -fn mk_rec_fields(fields: ~[ast::ty_field]) -> ~[field] { - do fields.map |field| { - { - span: field.span, - ident: field.node.ident, - mutbl: field.node.mt.mutbl, - } - } -} - -fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] { - do fields.map |field| { - let (ident, mutbl) = match field.node.kind { - ast::named_field(ident, mutbl, _) => (ident, mutbl), - _ => fail ~"[auto_serialize2] does not support \ - unnamed fields", - }; - - { - span: field.span, - ident: ident, - mutbl: match mutbl { - ast::class_mutable => ast::m_mutbl, - ast::class_immutable => ast::m_imm, - }, - } - } -} - -fn mk_ser_fields( - cx: ext_ctxt, - span: span, - fields: ~[field] -) -> ~[@ast::stmt] { - do fields.mapi |idx, field| { - // ast for `|| self.$(name).serialize(__s)` - let expr_lambda = cx.lambda_expr( - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"self"), - field.ident - ), - cx.ident_of(~"serialize") - ), - ~[cx.expr_var(span, ~"__s")] - ) - ); - - // ast for `__s.emit_field($(name), $(idx), $(expr_lambda))` - cx.stmt( - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_field") - ), - ~[ - cx.lit_str(span, @cx.str_of(field.ident)), - cx.lit_uint(span, idx), - expr_lambda, - ] - ) - ) - } -} - -fn mk_deser_fields( - cx: ext_ctxt, - span: span, - fields: ~[{ span: span, ident: ast::ident, mutbl: ast::mutability }] -) -> ~[ast::field] { - do fields.mapi |idx, field| { - // ast for `|| std::serialization2::deserialize(__d)` - let expr_lambda = cx.lambda( - cx.expr_blk( - cx.expr_call( - span, - cx.expr_path(span, ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization2"), - cx.ident_of(~"deserialize"), - ]), - ~[cx.expr_var(span, ~"__d")] - ) - ) - ); - - // ast for `__d.read_field($(name), $(idx), $(expr_lambda))` - let expr: @ast::expr = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_field") - ), - ~[ - cx.lit_str(span, @cx.str_of(field.ident)), - cx.lit_uint(span, idx), - expr_lambda, - ] - ); - - { - node: { mutbl: field.mutbl, ident: field.ident, expr: expr }, - span: span, - } - } -} - -fn mk_enum_ser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - enum_def: ast::enum_def, - tps: ~[ast::ty_param] -) -> @ast::item { - let body = mk_enum_ser_body( - cx, - span, - ident, - enum_def.variants - ); - - mk_ser_impl(cx, span, ident, tps, body) -} - -fn mk_enum_deser_impl( - cx: ext_ctxt, - span: span, - ident: ast::ident, - enum_def: ast::enum_def, - tps: ~[ast::ty_param] -) -> @ast::item { - let body = mk_enum_deser_body( - cx, - span, - ident, - enum_def.variants - ); - - mk_deser_impl(cx, span, ident, tps, body) -} - -fn ser_variant( - cx: ext_ctxt, - span: span, - v_name: ast::ident, - v_idx: uint, - args: ~[ast::variant_arg] -) -> ast::arm { - // Name the variant arguments. - let names = args.mapi(|i, _arg| cx.ident_of(fmt!("__v%u", i))); - - // Bind the names to the variant argument type. - let pats = args.mapi(|i, arg| cx.binder_pat(arg.ty.span, names[i])); - - let pat_node = if pats.is_empty() { - ast::pat_ident( - ast::bind_by_implicit_ref, - cx.path(span, ~[v_name]), - None - ) - } else { - ast::pat_enum( - cx.path(span, ~[v_name]), - Some(pats) - ) - }; - - let pat = @{ - id: cx.next_id(), - node: pat_node, - span: span, - }; - - let stmts = do args.mapi |a_idx, _arg| { - // ast for `__s.emit_enum_variant_arg` - let expr_emit = cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_enum_variant_arg") - ); - - // ast for `|| $(v).serialize(__s)` - let expr_serialize = cx.lambda_expr( - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_path(span, ~[names[a_idx]]), - cx.ident_of(~"serialize") - ), - ~[cx.expr_var(span, ~"__s")] - ) - ); - - // ast for `$(expr_emit)($(a_idx), $(expr_serialize))` - cx.stmt( - cx.expr_call( - span, - expr_emit, - ~[cx.lit_uint(span, a_idx), expr_serialize] - ) - ) - }; - - // ast for `__s.emit_enum_variant($(name), $(idx), $(sz), $(lambda))` - let body = cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_enum_variant") - ), - ~[ - cx.lit_str(span, @cx.str_of(v_name)), - cx.lit_uint(span, v_idx), - cx.lit_uint(span, stmts.len()), - cx.lambda_stmts(span, stmts), - ] - ); - - { pats: ~[pat], guard: None, body: cx.expr_blk(body) } -} - -fn mk_enum_ser_body( - cx: ext_ctxt, - span: span, - name: ast::ident, - variants: ~[ast::variant] -) -> @ast::expr { - let arms = do variants.mapi |v_idx, variant| { - match variant.node.kind { - ast::tuple_variant_kind(args) => - ser_variant(cx, span, variant.node.name, v_idx, args), - ast::struct_variant_kind(*) => - fail ~"struct variants unimplemented", - ast::enum_variant_kind(*) => - fail ~"enum variants unimplemented", - } - }; - - // ast for `match *self { $(arms) }` - let match_expr = cx.expr( - span, - ast::expr_match( - cx.expr( - span, - ast::expr_unary(ast::deref, cx.expr_var(span, ~"self")) - ), - arms - ) - ); - - // ast for `__s.emit_enum($(name), || $(match_expr))` - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__s"), - cx.ident_of(~"emit_enum") - ), - ~[ - cx.lit_str(span, @cx.str_of(name)), - cx.lambda_expr(match_expr), - ] - ) -} - -fn mk_enum_deser_variant_nary( - cx: ext_ctxt, - span: span, - name: ast::ident, - args: ~[ast::variant_arg] -) -> @ast::expr { - let args = do args.mapi |idx, _arg| { - // ast for `|| std::serialization2::deserialize(__d)` - let expr_lambda = cx.lambda_expr( - cx.expr_call( - span, - cx.expr_path(span, ~[ - cx.ident_of(~"std"), - cx.ident_of(~"serialization2"), - cx.ident_of(~"deserialize"), - ]), - ~[cx.expr_var(span, ~"__d")] - ) - ); - - // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))` - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum_variant_arg") - ), - ~[cx.lit_uint(span, idx), expr_lambda] - ) - }; - - // ast for `$(name)($(args))` - cx.expr_call(span, cx.expr_path(span, ~[name]), args) -} - -fn mk_enum_deser_body( - cx: ext_ctxt, - span: span, - name: ast::ident, - variants: ~[ast::variant] -) -> @ast::expr { - let mut arms = do variants.mapi |v_idx, variant| { - let body = match variant.node.kind { - ast::tuple_variant_kind(args) => { - if args.is_empty() { - // for a nullary variant v, do "v" - cx.expr_path(span, ~[variant.node.name]) - } else { - // for an n-ary variant v, do "v(a_1, ..., a_n)" - mk_enum_deser_variant_nary( - cx, - span, - variant.node.name, - args - ) - } - }, - ast::struct_variant_kind(*) => - fail ~"struct variants unimplemented", - ast::enum_variant_kind(*) => - fail ~"enum variants unimplemented", - }; - - let pat = @{ - id: cx.next_id(), - node: ast::pat_lit(cx.lit_uint(span, v_idx)), - span: span, - }; - - { - pats: ~[pat], - guard: None, - body: cx.expr_blk(body), - } - }; - - let impossible_case = { - pats: ~[@{ id: cx.next_id(), node: ast::pat_wild, span: span}], - guard: None, - - // FIXME(#3198): proper error message - body: cx.expr_blk(cx.expr(span, ast::expr_fail(None))), - }; - - arms.push(impossible_case); - - // ast for `|i| { match i { $(arms) } }` - let expr_lambda = cx.expr( - span, - ast::expr_fn_block( - { - inputs: ~[{ - mode: ast::infer(cx.next_id()), - ty: @{ - id: cx.next_id(), - node: ast::ty_infer, - span: span - }, - ident: cx.ident_of(~"i"), - id: cx.next_id(), - }], - output: @{ - id: cx.next_id(), - node: ast::ty_infer, - span: span, - }, - cf: ast::return_val, - }, - cx.expr_blk( - cx.expr( - span, - ast::expr_match(cx.expr_var(span, ~"i"), arms) - ) - ), - @~[] - ) - ); - - // ast for `__d.read_enum_variant($(expr_lambda))` - let expr_lambda = cx.lambda_expr( - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum_variant") - ), - ~[expr_lambda] - ) - ); - - // ast for `__d.read_enum($(e_name), $(expr_lambda))` - cx.expr_call( - span, - cx.expr_field( - span, - cx.expr_var(span, ~"__d"), - cx.ident_of(~"read_enum") - ), - ~[ - cx.lit_str(span, @cx.str_of(name)), - expr_lambda - ] - ) -} diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 794c5233e21..c106042b9a3 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -54,7 +54,7 @@ enum syntax_extension { // macro_defining() is obsolete, remove when #old_macros go away. macro_defining(macro_definer), - // #[auto_serialize2] and such. will probably survive death of #old_macros + // #[auto_serialize] and such. will probably survive death of #old_macros item_decorator(item_decorator), // Token-tree expanders @@ -64,67 +64,6 @@ enum syntax_extension { // A temporary hard-coded map of methods for expanding syntax extension // AST nodes into full ASTs -#[cfg(stage0)] -fn syntax_expander_table() -> HashMap<~str, syntax_extension> { - fn builtin(f: syntax_expander_) -> syntax_extension - {normal({expander: f, span: None})} - fn builtin_expr_tt(f: syntax_expander_tt_) -> syntax_extension { - expr_tt({expander: f, span: None}) - } - fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension { - item_tt({expander: f, span: None}) - } - let syntax_expanders = HashMap(); - syntax_expanders.insert(~"macro", - macro_defining(ext::simplext::add_new_extension)); - syntax_expanders.insert(~"macro_rules", - builtin_item_tt( - ext::tt::macro_rules::add_new_extension)); - syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext)); - syntax_expanders.insert(~"auto_serialize", - item_decorator(ext::auto_serialize::expand)); - syntax_expanders.insert( - ~"auto_serialize2", - item_decorator(ext::auto_serialize2::expand_auto_serialize)); - syntax_expanders.insert( - ~"auto_deserialize2", - item_decorator(ext::auto_serialize2::expand_auto_deserialize)); - syntax_expanders.insert(~"env", builtin(ext::env::expand_syntax_ext)); - syntax_expanders.insert(~"concat_idents", - builtin(ext::concat_idents::expand_syntax_ext)); - syntax_expanders.insert(~"ident_to_str", - builtin(ext::ident_to_str::expand_syntax_ext)); - syntax_expanders.insert(~"log_syntax", - builtin_expr_tt( - ext::log_syntax::expand_syntax_ext)); - syntax_expanders.insert(~"ast", - builtin(ext::qquote::expand_ast)); - syntax_expanders.insert(~"line", - builtin(ext::source_util::expand_line)); - syntax_expanders.insert(~"col", - builtin(ext::source_util::expand_col)); - syntax_expanders.insert(~"file", - builtin(ext::source_util::expand_file)); - syntax_expanders.insert(~"stringify", - builtin(ext::source_util::expand_stringify)); - syntax_expanders.insert(~"include", - builtin(ext::source_util::expand_include)); - syntax_expanders.insert(~"include_str", - builtin(ext::source_util::expand_include_str)); - syntax_expanders.insert(~"include_bin", - builtin(ext::source_util::expand_include_bin)); - syntax_expanders.insert(~"module_path", - builtin(ext::source_util::expand_mod)); - syntax_expanders.insert(~"proto", - builtin_item_tt(ext::pipes::expand_proto)); - syntax_expanders.insert( - ~"trace_macros", - builtin_expr_tt(ext::trace_macros::expand_trace_macros)); - return syntax_expanders; -} - -#[cfg(stage1)] -#[cfg(stage2)] fn syntax_expander_table() -> HashMap<~str, syntax_extension> { fn builtin(f: syntax_expander_) -> syntax_extension {normal({expander: f, span: None})} @@ -143,16 +82,10 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> { syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext)); syntax_expanders.insert( ~"auto_serialize", - item_decorator(ext::auto_serialize2::expand_auto_serialize)); + item_decorator(ext::auto_serialize::expand_auto_serialize)); syntax_expanders.insert( ~"auto_deserialize", - item_decorator(ext::auto_serialize2::expand_auto_deserialize)); - syntax_expanders.insert( - ~"auto_serialize2", - item_decorator(ext::auto_serialize2::expand_auto_serialize)); - syntax_expanders.insert( - ~"auto_deserialize2", - item_decorator(ext::auto_serialize2::expand_auto_deserialize)); + item_decorator(ext::auto_serialize::expand_auto_deserialize)); syntax_expanders.insert(~"env", builtin(ext::env::expand_syntax_ext)); syntax_expanders.insert(~"concat_idents", builtin(ext::concat_idents::expand_syntax_ext)); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2d0b2f4c80a..22e2cfcde6b 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -124,7 +124,7 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, } // This is a secondary mechanism for invoking syntax extensions on items: -// "decorator" attributes, such as #[auto_serialize2]. These are invoked by an +// "decorator" attributes, such as #[auto_serialize]. These are invoked by an // attribute prefixing an item, and are interpreted by feeding the item // through the named attribute _as a syntax extension_ and splicing in the // resulting item vec into place in favour of the decorator. Note that diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 19e79a4ae7a..dce4dc3bbc7 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -2,8 +2,8 @@ use util::interner; use util::interner::interner; use std::map::HashMap; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum binop { PLUS, MINUS, @@ -17,8 +17,8 @@ enum binop { SHR, } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum token { /* Expression-operator symbols. */ EQ, @@ -75,8 +75,8 @@ enum token { EOF, } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] /// For interpolation during macro expansion. enum nonterminal { nt_item(@ast::item), diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 4a6bac9cd64..93ed5bd471b 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -128,12 +128,9 @@ mod ext { mod ident_to_str; #[legacy_exports] mod log_syntax; - #[cfg(stage0)] #[legacy_exports] mod auto_serialize; #[legacy_exports] - mod auto_serialize2; - #[legacy_exports] mod source_util; mod pipes { diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index 197e567ab2f..6b8c995ffd2 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -1,8 +1,9 @@ // Decoding metadata from a single crate's metadata -use std::{ebml2, map}; +use std::ebml; +use std::map; use std::map::HashMap; -use std::serialization2::deserialize; +use std::serialization::deserialize; use io::WriterUtil; use dvec::DVec; use syntax::{ast, ast_util}; @@ -64,25 +65,25 @@ export translate_def_id; // what crate that's in and give us a def_id that makes sense for the current // build. -fn lookup_hash(d: ebml2::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) -> - Option { - let index = ebml2::get_doc(d, tag_index); - let table = ebml2::get_doc(index, tag_index_table); +fn lookup_hash(d: ebml::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) -> + Option { + let index = ebml::get_doc(d, tag_index); + let table = ebml::get_doc(index, tag_index_table); let hash_pos = table.start + hash % 256u * 4u; let pos = io::u64_from_be_bytes(*d.data, hash_pos, 4u) as uint; - let tagged_doc = ebml2::doc_at(d.data, pos); + let tagged_doc = ebml::doc_at(d.data, pos); let belt = tag_index_buckets_bucket_elt; - for ebml2::tagged_docs(tagged_doc.doc, belt) |elt| { + for ebml::tagged_docs(tagged_doc.doc, belt) |elt| { let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4u) as uint; if eq_fn(vec::view(*elt.data, elt.start + 4u, elt.end)) { - return Some(ebml2::doc_at(d.data, pos).doc); + return Some(ebml::doc_at(d.data, pos).doc); } }; None } -fn maybe_find_item(item_id: int, items: ebml2::Doc) -> Option { +fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option { fn eq_item(bytes: &[u8], item_id: int) -> bool { return io::u64_from_be_bytes(vec::view(bytes, 0u, 4u), 0u, 4u) as int == item_id; @@ -92,14 +93,14 @@ fn maybe_find_item(item_id: int, items: ebml2::Doc) -> Option { item_id.hash() as uint) } -fn find_item(item_id: int, items: ebml2::Doc) -> ebml2::Doc { +fn find_item(item_id: int, items: ebml::Doc) -> ebml::Doc { return maybe_find_item(item_id, items).get(); } -// Looks up an item in the given metadata and returns an ebml2 doc pointing +// Looks up an item in the given metadata and returns an ebml doc pointing // to the item data. -fn lookup_item(item_id: int, data: @~[u8]) -> ebml2::Doc { - let items = ebml2::get_doc(ebml2::Doc(data), tag_items); +fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc { + let items = ebml::get_doc(ebml::Doc(data), tag_items); match maybe_find_item(item_id, items) { None => fail(fmt!("lookup_item: id not found: %d", item_id)), Some(d) => d @@ -137,9 +138,9 @@ impl Family : cmp::Eq { pure fn ne(other: &Family) -> bool { !self.eq(other) } } -fn item_family(item: ebml2::Doc) -> Family { - let fam = ebml2::get_doc(item, tag_items_data_item_family); - match ebml2::doc_as_u8(fam) as char { +fn item_family(item: ebml::Doc) -> Family { + let fam = ebml::get_doc(item, tag_items_data_item_family); + match ebml::doc_as_u8(fam) as char { 'c' => Const, 'f' => Fn, 'u' => UnsafeFn, @@ -165,59 +166,59 @@ fn item_family(item: ebml2::Doc) -> Family { } } -fn item_symbol(item: ebml2::Doc) -> ~str { - let sym = ebml2::get_doc(item, tag_items_data_item_symbol); - return str::from_bytes(ebml2::doc_data(sym)); +fn item_symbol(item: ebml::Doc) -> ~str { + let sym = ebml::get_doc(item, tag_items_data_item_symbol); + return str::from_bytes(ebml::doc_data(sym)); } -fn item_parent_item(d: ebml2::Doc) -> Option { - for ebml2::tagged_docs(d, tag_items_data_parent_item) |did| { - return Some(ebml2::with_doc_data(did, |d| parse_def_id(d))); +fn item_parent_item(d: ebml::Doc) -> Option { + for ebml::tagged_docs(d, tag_items_data_parent_item) |did| { + return Some(ebml::with_doc_data(did, |d| parse_def_id(d))); } None } -fn item_def_id(d: ebml2::Doc, cdata: cmd) -> ast::def_id { - let tagdoc = ebml2::get_doc(d, tag_def_id); - return translate_def_id(cdata, ebml2::with_doc_data(tagdoc, +fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id { + let tagdoc = ebml::get_doc(d, tag_def_id); + return translate_def_id(cdata, ebml::with_doc_data(tagdoc, |d| parse_def_id(d))); } -fn each_reexport(d: ebml2::Doc, f: fn(ebml2::Doc) -> bool) { - for ebml2::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| { +fn each_reexport(d: ebml::Doc, f: fn(ebml::Doc) -> bool) { + for ebml::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| { if !f(reexport_doc) { return; } } } -fn field_mutability(d: ebml2::Doc) -> ast::class_mutability { +fn field_mutability(d: ebml::Doc) -> ast::class_mutability { // Use maybe_get_doc in case it's a method option::map_default( - &ebml2::maybe_get_doc(d, tag_class_mut), + &ebml::maybe_get_doc(d, tag_class_mut), ast::class_immutable, |d| { - match ebml2::doc_as_u8(*d) as char { + match ebml::doc_as_u8(*d) as char { 'm' => ast::class_mutable, _ => ast::class_immutable } }) } -fn variant_disr_val(d: ebml2::Doc) -> Option { - do option::chain(ebml2::maybe_get_doc(d, tag_disr_val)) |val_doc| { - int::parse_bytes(ebml2::doc_data(val_doc), 10u) +fn variant_disr_val(d: ebml::Doc) -> Option { + do option::chain(ebml::maybe_get_doc(d, tag_disr_val)) |val_doc| { + int::parse_bytes(ebml::doc_data(val_doc), 10u) } } -fn doc_type(doc: ebml2::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t { - let tp = ebml2::get_doc(doc, tag_items_data_item_type); +fn doc_type(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t { + let tp = ebml::get_doc(doc, tag_items_data_item_type); parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, |did| { translate_def_id(cdata, did) }) } -fn item_type(item_id: ast::def_id, item: ebml2::Doc, +fn item_type(item_id: ast::def_id, item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t { let t = doc_type(item, tcx, cdata); if family_names_type(item_family(item)) { @@ -225,18 +226,18 @@ fn item_type(item_id: ast::def_id, item: ebml2::Doc, } else { t } } -fn item_impl_traits(item: ebml2::Doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] { +fn item_impl_traits(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] { let mut results = ~[]; - for ebml2::tagged_docs(item, tag_impl_trait) |ity| { + for ebml::tagged_docs(item, tag_impl_trait) |ity| { results.push(doc_type(ity, tcx, cdata)); }; results } -fn item_ty_param_bounds(item: ebml2::Doc, tcx: ty::ctxt, cdata: cmd) +fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> @~[ty::param_bounds] { let mut bounds = ~[]; - for ebml2::tagged_docs(item, tag_items_data_item_ty_param_bounds) |p| { + for ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds) |p| { let bd = parse_bounds_data(p.data, p.start, cdata.cnum, tcx, |did| { translate_def_id(cdata, did) }); @@ -245,42 +246,42 @@ fn item_ty_param_bounds(item: ebml2::Doc, tcx: ty::ctxt, cdata: cmd) @bounds } -fn item_ty_region_param(item: ebml2::Doc) -> Option { - ebml2::maybe_get_doc(item, tag_region_param).map(|doc| { - deserialize(&ebml2::Deserializer(*doc)) +fn item_ty_region_param(item: ebml::Doc) -> Option { + ebml::maybe_get_doc(item, tag_region_param).map(|doc| { + deserialize(&ebml::Deserializer(*doc)) }) } -fn item_ty_param_count(item: ebml2::Doc) -> uint { +fn item_ty_param_count(item: ebml::Doc) -> uint { let mut n = 0u; - ebml2::tagged_docs(item, tag_items_data_item_ty_param_bounds, + ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds, |_p| { n += 1u; true } ); n } -fn enum_variant_ids(item: ebml2::Doc, cdata: cmd) -> ~[ast::def_id] { +fn enum_variant_ids(item: ebml::Doc, cdata: cmd) -> ~[ast::def_id] { let mut ids: ~[ast::def_id] = ~[]; let v = tag_items_data_item_variant; - for ebml2::tagged_docs(item, v) |p| { - let ext = ebml2::with_doc_data(p, |d| parse_def_id(d)); + for ebml::tagged_docs(item, v) |p| { + let ext = ebml::with_doc_data(p, |d| parse_def_id(d)); ids.push({crate: cdata.cnum, node: ext.node}); }; return ids; } -fn item_path(intr: @ident_interner, item_doc: ebml2::Doc) -> ast_map::path { - let path_doc = ebml2::get_doc(item_doc, tag_path); +fn item_path(intr: @ident_interner, item_doc: ebml::Doc) -> ast_map::path { + let path_doc = ebml::get_doc(item_doc, tag_path); - let len_doc = ebml2::get_doc(path_doc, tag_path_len); - let len = ebml2::doc_as_u32(len_doc) as uint; + let len_doc = ebml::get_doc(path_doc, tag_path_len); + let len = ebml::doc_as_u32(len_doc) as uint; let mut result = vec::with_capacity(len); - for ebml2::docs(path_doc) |tag, elt_doc| { + for ebml::docs(path_doc) |tag, elt_doc| { if tag == tag_path_elt_mod { - let str = ebml2::doc_as_str(elt_doc); + let str = ebml::doc_as_str(elt_doc); result.push(ast_map::path_mod(intr.intern(@str))); } else if tag == tag_path_elt_name { - let str = ebml2::doc_as_str(elt_doc); + let str = ebml::doc_as_str(elt_doc); result.push(ast_map::path_name(intr.intern(@str))); } else { // ignore tag_path_len element @@ -290,12 +291,12 @@ fn item_path(intr: @ident_interner, item_doc: ebml2::Doc) -> ast_map::path { return result; } -fn item_name(intr: @ident_interner, item: ebml2::Doc) -> ast::ident { - let name = ebml2::get_doc(item, tag_paths_data_name); - intr.intern(@str::from_bytes(ebml2::doc_data(name))) +fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident { + let name = ebml::get_doc(item, tag_paths_data_name); + intr.intern(@str::from_bytes(ebml::doc_data(name))) } -fn item_to_def_like(item: ebml2::Doc, did: ast::def_id, cnum: ast::crate_num) +fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num) -> def_like { let fam = item_family(item); match fam { @@ -367,10 +368,10 @@ fn get_impl_traits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> ~[ty::t] { fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, name: ast::ident) -> ast::def_id { - let items = ebml2::get_doc(ebml2::Doc(cdata.data), tag_items); + let items = ebml::get_doc(ebml::Doc(cdata.data), tag_items); let mut found = None; - for ebml2::tagged_docs(find_item(id, items), tag_item_impl_method) |mid| { - let m_did = ebml2::with_doc_data(mid, |d| parse_def_id(d)); + for ebml::tagged_docs(find_item(id, items), tag_item_impl_method) |mid| { + let m_did = ebml::with_doc_data(mid, |d| parse_def_id(d)); if item_name(intr, find_item(m_did.node, items)) == name { found = Some(translate_def_id(cdata, m_did)); } @@ -380,14 +381,14 @@ fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, fn get_class_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, name: ast::ident) -> ast::def_id { - let items = ebml2::get_doc(ebml2::Doc(cdata.data), tag_items); + let items = ebml::get_doc(ebml::Doc(cdata.data), tag_items); let mut found = None; let cls_items = match maybe_find_item(id, items) { Some(it) => it, None => fail (fmt!("get_class_method: class id not found \ when looking up method %s", *intr.get(name))) }; - for ebml2::tagged_docs(cls_items, tag_item_trait_method) |mid| { + for ebml::tagged_docs(cls_items, tag_item_trait_method) |mid| { let m_did = item_def_id(mid, cdata); if item_name(intr, mid) == name { found = Some(m_did); @@ -401,16 +402,16 @@ fn get_class_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, } fn class_dtor(cdata: cmd, id: ast::node_id) -> Option { - let items = ebml2::get_doc(ebml2::Doc(cdata.data), tag_items); + let items = ebml::get_doc(ebml::Doc(cdata.data), tag_items); let mut found = None; let cls_items = match maybe_find_item(id, items) { Some(it) => it, None => fail (fmt!("class_dtor: class id not found \ when looking up dtor for %d", id)) }; - for ebml2::tagged_docs(cls_items, tag_item_dtor) |doc| { - let doc1 = ebml2::get_doc(doc, tag_def_id); - let did = ebml2::with_doc_data(doc1, |d| parse_def_id(d)); + for ebml::tagged_docs(cls_items, tag_item_dtor) |doc| { + let doc1 = ebml::get_doc(doc, tag_def_id); + let did = ebml::with_doc_data(doc1, |d| parse_def_id(d)); found = Some(translate_def_id(cdata, did)); }; found @@ -452,14 +453,14 @@ fn path_entry(path_string: ~str, def_like: def_like) -> path_entry { /// Iterates over all the paths in the given crate. fn each_path(intr: @ident_interner, cdata: cmd, f: fn(path_entry) -> bool) { - let root = ebml2::Doc(cdata.data); - let items = ebml2::get_doc(root, tag_items); - let items_data = ebml2::get_doc(items, tag_items_data); + let root = ebml::Doc(cdata.data); + let items = ebml::get_doc(root, tag_items); + let items_data = ebml::get_doc(items, tag_items_data); let mut broken = false; // First, go through all the explicit items. - for ebml2::tagged_docs(items_data, tag_items_data_item) |item_doc| { + for ebml::tagged_docs(items_data, tag_items_data_item) |item_doc| { if !broken { let path = ast_map::path_to_str_with_sep( item_path(intr, item_doc), ~"::", intr); @@ -482,16 +483,16 @@ fn each_path(intr: @ident_interner, cdata: cmd, f: fn(path_entry) -> bool) { for each_reexport(item_doc) |reexport_doc| { if !broken { let def_id_doc = - ebml2::get_doc(reexport_doc, + ebml::get_doc(reexport_doc, tag_items_data_item_reexport_def_id); let def_id = - ebml2::with_doc_data(def_id_doc, |d| parse_def_id(d)); + ebml::with_doc_data(def_id_doc, |d| parse_def_id(d)); let def_id = translate_def_id(cdata, def_id); let reexport_name_doc = - ebml2::get_doc(reexport_doc, + ebml::get_doc(reexport_doc, tag_items_data_item_reexport_name); - let reexport_name = ebml2::doc_as_str(reexport_name_doc); + let reexport_name = ebml::doc_as_str(reexport_name_doc); let reexport_path; if path == ~"" { @@ -540,7 +541,7 @@ type decode_inlined_item = fn( cdata: cstore::crate_metadata, tcx: ty::ctxt, path: ast_map::path, - par_doc: ebml2::Doc) -> Option; + par_doc: ebml::Doc) -> Option; fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt, id: ast::node_id, @@ -571,7 +572,7 @@ fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt, fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> ~[ty::variant_info] { let data = cdata.data; - let items = ebml2::get_doc(ebml2::Doc(data), tag_items); + let items = ebml::get_doc(ebml::Doc(data), tag_items); let item = find_item(id, items); let mut infos: ~[ty::variant_info] = ~[]; let variant_ids = enum_variant_ids(item, cdata); @@ -609,7 +610,7 @@ type method_info = { type _impl = {did: ast::def_id, ident: ast::ident, methods: ~[@method_info]}; -fn get_self_ty(item: ebml2::Doc) -> ast::self_ty_ { +fn get_self_ty(item: ebml::Doc) -> ast::self_ty_ { fn get_mutability(ch: u8) -> ast::mutability { match ch as char { 'i' => { ast::m_imm } @@ -621,8 +622,8 @@ fn get_self_ty(item: ebml2::Doc) -> ast::self_ty_ { } } - let self_type_doc = ebml2::get_doc(item, tag_item_trait_method_self_ty); - let string = ebml2::doc_as_str(self_type_doc); + let self_type_doc = ebml::get_doc(item, tag_item_trait_method_self_ty); + let string = ebml::doc_as_str(self_type_doc); let self_ty_kind = string[0]; match self_ty_kind as char { @@ -638,11 +639,11 @@ fn get_self_ty(item: ebml2::Doc) -> ast::self_ty_ { } } -fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml2::Doc, +fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc, base_tps: uint) -> ~[@method_info] { let mut rslt = ~[]; - for ebml2::tagged_docs(item, tag_item_impl_method) |doc| { - let m_did = ebml2::with_doc_data(doc, |d| parse_def_id(d)); + for ebml::tagged_docs(item, tag_item_impl_method) |doc| { + let m_did = ebml::with_doc_data(doc, |d| parse_def_id(d)); let mth_item = lookup_item(m_did.node, cdata.data); let self_ty = get_self_ty(mth_item); rslt.push(@{did: translate_def_id(cdata, m_did), @@ -662,8 +663,8 @@ fn get_impls_for_mod(intr: @ident_interner, cdata: cmd, let data = cdata.data; let mod_item = lookup_item(m_id, data); let mut result = ~[]; - for ebml2::tagged_docs(mod_item, tag_mod_impl) |doc| { - let did = ebml2::with_doc_data(doc, |d| parse_def_id(d)); + for ebml::tagged_docs(mod_item, tag_mod_impl) |doc| { + let did = ebml::with_doc_data(doc, |d| parse_def_id(d)); let local_did = translate_def_id(cdata, did); debug!("(get impls for mod) getting did %? for '%?'", local_did, name); @@ -690,7 +691,7 @@ fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id, let data = cdata.data; let item = lookup_item(id, data); let mut result = ~[]; - for ebml2::tagged_docs(item, tag_item_trait_method) |mth| { + for ebml::tagged_docs(item, tag_item_trait_method) |mth| { let bounds = item_ty_param_bounds(mth, tcx, cdata); let name = item_name(intr, mth); let ty = doc_type(mth, tcx, cdata); @@ -722,7 +723,7 @@ fn get_method_names_if_trait(intr: @ident_interner, cdata: cmd, } let resulting_methods = @DVec(); - for ebml2::tagged_docs(item, tag_item_trait_method) |method| { + for ebml::tagged_docs(item, tag_item_trait_method) |method| { resulting_methods.push( (item_name(intr, method), get_self_ty(method))); } @@ -734,8 +735,8 @@ fn get_item_attrs(cdata: cmd, f: fn(~[@ast::meta_item])) { let item = lookup_item(node_id, cdata.data); - for ebml2::tagged_docs(item, tag_attributes) |attributes| { - for ebml2::tagged_docs(attributes, tag_attribute) |attribute| { + for ebml::tagged_docs(item, tag_attributes) |attributes| { + for ebml::tagged_docs(attributes, tag_attribute) |attribute| { f(get_meta_items(attribute)); } } @@ -747,7 +748,7 @@ fn get_class_members(intr: @ident_interner, cdata: cmd, id: ast::node_id, let data = cdata.data; let item = lookup_item(id, data); let mut result = ~[]; - for ebml2::tagged_docs(item, tag_item_field) |an_item| { + for ebml::tagged_docs(item, tag_item_field) |an_item| { let f = item_family(an_item); if p(f) { let name = item_name(intr, an_item); @@ -787,15 +788,15 @@ fn family_names_type(fam: Family) -> bool { match fam { Type | Mod | Trait => true, _ => false } } -fn read_path(d: ebml2::Doc) -> {path: ~str, pos: uint} { - let desc = ebml2::doc_data(d); +fn read_path(d: ebml::Doc) -> {path: ~str, pos: uint} { + let desc = ebml::doc_data(d); let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint; let pathbytes = vec::slice::(desc, 4u, vec::len::(desc)); let path = str::from_bytes(pathbytes); return {path: path, pos: pos}; } -fn describe_def(items: ebml2::Doc, id: ast::def_id) -> ~str { +fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str { if id.crate != ast::local_crate { return ~"external"; } let it = match maybe_find_item(id.node, items) { Some(it) => it, @@ -830,36 +831,36 @@ fn item_family_to_str(fam: Family) -> ~str { } } -fn get_meta_items(md: ebml2::Doc) -> ~[@ast::meta_item] { +fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { let mut items: ~[@ast::meta_item] = ~[]; - for ebml2::tagged_docs(md, tag_meta_item_word) |meta_item_doc| { - let nd = ebml2::get_doc(meta_item_doc, tag_meta_item_name); - let n = str::from_bytes(ebml2::doc_data(nd)); + for ebml::tagged_docs(md, tag_meta_item_word) |meta_item_doc| { + let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); + let n = str::from_bytes(ebml::doc_data(nd)); items.push(attr::mk_word_item(n)); }; - for ebml2::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| { - let nd = ebml2::get_doc(meta_item_doc, tag_meta_item_name); - let vd = ebml2::get_doc(meta_item_doc, tag_meta_item_value); - let n = str::from_bytes(ebml2::doc_data(nd)); - let v = str::from_bytes(ebml2::doc_data(vd)); + for ebml::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| { + let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); + let vd = ebml::get_doc(meta_item_doc, tag_meta_item_value); + let n = str::from_bytes(ebml::doc_data(nd)); + let v = str::from_bytes(ebml::doc_data(vd)); // FIXME (#623): Should be able to decode meta_name_value variants, // but currently the encoder just drops them items.push(attr::mk_name_value_item_str(n, v)); }; - for ebml2::tagged_docs(md, tag_meta_item_list) |meta_item_doc| { - let nd = ebml2::get_doc(meta_item_doc, tag_meta_item_name); - let n = str::from_bytes(ebml2::doc_data(nd)); + for ebml::tagged_docs(md, tag_meta_item_list) |meta_item_doc| { + let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); + let n = str::from_bytes(ebml::doc_data(nd)); let subitems = get_meta_items(meta_item_doc); items.push(attr::mk_list_item(n, subitems)); }; return items; } -fn get_attributes(md: ebml2::Doc) -> ~[ast::attribute] { +fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] { let mut attrs: ~[ast::attribute] = ~[]; - match ebml2::maybe_get_doc(md, tag_attributes) { + match ebml::maybe_get_doc(md, tag_attributes) { option::Some(attrs_d) => { - for ebml2::tagged_docs(attrs_d, tag_attribute) |attr_doc| { + for ebml::tagged_docs(attrs_d, tag_attribute) |attr_doc| { let meta_items = get_meta_items(attr_doc); // Currently it's only possible to have a single meta item on // an attribute @@ -877,13 +878,13 @@ fn get_attributes(md: ebml2::Doc) -> ~[ast::attribute] { } fn list_meta_items(intr: @ident_interner, - meta_items: ebml2::Doc, out: io::Writer) { + meta_items: ebml::Doc, out: io::Writer) { for get_meta_items(meta_items).each |mi| { out.write_str(fmt!("%s\n", pprust::meta_item_to_str(*mi, intr))); } } -fn list_crate_attributes(intr: @ident_interner, md: ebml2::Doc, hash: ~str, +fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: ~str, out: io::Writer) { out.write_str(fmt!("=Crate Attributes (%s)=\n", hash)); @@ -895,7 +896,7 @@ fn list_crate_attributes(intr: @ident_interner, md: ebml2::Doc, hash: ~str, } fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] { - return get_attributes(ebml2::Doc(data)); + return get_attributes(ebml::Doc(data)); } type crate_dep = {cnum: ast::crate_num, name: ast::ident, @@ -903,13 +904,13 @@ type crate_dep = {cnum: ast::crate_num, name: ast::ident, fn get_crate_deps(intr: @ident_interner, data: @~[u8]) -> ~[crate_dep] { let mut deps: ~[crate_dep] = ~[]; - let cratedoc = ebml2::Doc(data); - let depsdoc = ebml2::get_doc(cratedoc, tag_crate_deps); + let cratedoc = ebml::Doc(data); + let depsdoc = ebml::get_doc(cratedoc, tag_crate_deps); let mut crate_num = 1; - fn docstr(doc: ebml2::Doc, tag_: uint) -> ~str { - str::from_bytes(ebml2::doc_data(ebml2::get_doc(doc, tag_))) + fn docstr(doc: ebml::Doc, tag_: uint) -> ~str { + str::from_bytes(ebml::doc_data(ebml::get_doc(doc, tag_))) } - for ebml2::tagged_docs(depsdoc, tag_crate_dep) |depdoc| { + for ebml::tagged_docs(depsdoc, tag_crate_dep) |depdoc| { deps.push({cnum: crate_num, name: intr.intern(@docstr(depdoc, tag_crate_dep_name)), vers: docstr(depdoc, tag_crate_dep_vers), @@ -932,9 +933,9 @@ fn list_crate_deps(intr: @ident_interner, data: @~[u8], out: io::Writer) { } fn get_crate_hash(data: @~[u8]) -> ~str { - let cratedoc = ebml2::Doc(data); - let hashdoc = ebml2::get_doc(cratedoc, tag_crate_hash); - return str::from_bytes(ebml2::doc_data(hashdoc)); + let cratedoc = ebml::Doc(data); + let hashdoc = ebml::get_doc(cratedoc, tag_crate_hash); + return str::from_bytes(ebml::doc_data(hashdoc)); } fn get_crate_vers(data: @~[u8]) -> ~str { @@ -988,7 +989,7 @@ fn get_crate_module_paths(intr: @ident_interner, cdata: cmd) fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8], out: io::Writer) { let hash = get_crate_hash(bytes); - let md = ebml2::Doc(bytes); + let md = ebml::Doc(bytes); list_crate_attributes(intr, md, hash, out); list_crate_deps(intr, bytes, out); } diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 95696a14156..f188d8ee5d8 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -2,10 +2,10 @@ use util::ppaux::ty_to_str; -use std::{ebml2, map}; +use std::{ebml, map}; use std::map::HashMap; use io::WriterUtil; -use ebml2::Serializer; +use ebml::Serializer; use syntax::ast::*; use syntax::print::pprust; use syntax::{ast_util, visit}; @@ -40,7 +40,7 @@ export encode_def_id; type abbrev_map = map::HashMap; type encode_inlined_item = fn@(ecx: @encode_ctxt, - ebml_w: ebml2::Serializer, + ebml_w: ebml::Serializer, path: ast_map::path, ii: ast::inlined_item); @@ -86,15 +86,15 @@ fn reachable(ecx: @encode_ctxt, id: node_id) -> bool { ecx.reachable.contains_key(id) } -fn encode_name(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, name: ident) { +fn encode_name(ecx: @encode_ctxt, ebml_w: ebml::Serializer, name: ident) { ebml_w.wr_tagged_str(tag_paths_data_name, ecx.tcx.sess.str_of(name)); } -fn encode_def_id(ebml_w: ebml2::Serializer, id: def_id) { +fn encode_def_id(ebml_w: ebml::Serializer, id: def_id) { ebml_w.wr_tagged_str(tag_def_id, def_to_str(id)); } -fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml::Serializer, it: @ast::item) { let opt_rp = ecx.tcx.region_paramd_items.find(it.id); for opt_rp.each |rp| { @@ -104,7 +104,7 @@ fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, } } -fn encode_mutability(ebml_w: ebml2::Serializer, mt: class_mutability) { +fn encode_mutability(ebml_w: ebml::Serializer, mt: class_mutability) { do ebml_w.wr_tag(tag_class_mut) { let val = match mt { class_immutable => 'a', @@ -116,7 +116,7 @@ fn encode_mutability(ebml_w: ebml2::Serializer, mt: class_mutability) { type entry = {val: T, pos: uint}; -fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, path: &[ident], +fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Serializer, path: &[ident], index: &mut ~[entry<~str>], name: ident) { let mut full_path = ~[]; full_path.push_all(path); @@ -127,7 +127,7 @@ fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, path: &[ident], pos: ebml_w.writer.tell()}); } -fn encode_trait_ref(ebml_w: ebml2::Serializer, ecx: @encode_ctxt, +fn encode_trait_ref(ebml_w: ebml::Serializer, ecx: @encode_ctxt, t: @trait_ref) { ebml_w.start_tag(tag_impl_trait); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id)); @@ -136,7 +136,7 @@ fn encode_trait_ref(ebml_w: ebml2::Serializer, ecx: @encode_ctxt, // Item info table encoding -fn encode_family(ebml_w: ebml2::Serializer, c: char) { +fn encode_family(ebml_w: ebml::Serializer, c: char) { ebml_w.start_tag(tag_items_data_item_family); ebml_w.writer.write(&[c as u8]); ebml_w.end_tag(); @@ -144,7 +144,7 @@ fn encode_family(ebml_w: ebml2::Serializer, c: char) { fn def_to_str(did: def_id) -> ~str { fmt!("%d:%d", did.crate, did.node) } -fn encode_ty_type_param_bounds(ebml_w: ebml2::Serializer, ecx: @encode_ctxt, +fn encode_ty_type_param_bounds(ebml_w: ebml::Serializer, ecx: @encode_ctxt, params: @~[ty::param_bounds]) { let ty_str_ctxt = @{diag: ecx.diag, ds: def_to_str, @@ -158,7 +158,7 @@ fn encode_ty_type_param_bounds(ebml_w: ebml2::Serializer, ecx: @encode_ctxt, } } -fn encode_type_param_bounds(ebml_w: ebml2::Serializer, ecx: @encode_ctxt, +fn encode_type_param_bounds(ebml_w: ebml::Serializer, ecx: @encode_ctxt, params: ~[ty_param]) { let ty_param_bounds = @params.map(|param| ecx.tcx.ty_param_bounds.get(param.id)); @@ -166,13 +166,13 @@ fn encode_type_param_bounds(ebml_w: ebml2::Serializer, ecx: @encode_ctxt, } -fn encode_variant_id(ebml_w: ebml2::Serializer, vid: def_id) { +fn encode_variant_id(ebml_w: ebml::Serializer, vid: def_id) { ebml_w.start_tag(tag_items_data_item_variant); ebml_w.writer.write(str::to_bytes(def_to_str(vid))); ebml_w.end_tag(); } -fn write_type(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, typ: ty::t) { +fn write_type(ecx: @encode_ctxt, ebml_w: ebml::Serializer, typ: ty::t) { let ty_str_ctxt = @{diag: ecx.diag, ds: def_to_str, @@ -182,7 +182,7 @@ fn write_type(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, typ: ty::t) { tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ); } -fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml::Serializer, vstore: ty::vstore) { let ty_str_ctxt = @{diag: ecx.diag, @@ -193,13 +193,13 @@ fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore); } -fn encode_type(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, typ: ty::t) { +fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::Serializer, typ: ty::t) { ebml_w.start_tag(tag_items_data_item_type); write_type(ecx, ebml_w, typ); ebml_w.end_tag(); } -fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, id: node_id) { +fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::Serializer, id: node_id) { ebml_w.start_tag(tag_items_data_item_symbol); let sym = match ecx.item_symbols.find(id) { Some(x) => x, @@ -212,27 +212,27 @@ fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, id: node_id) { ebml_w.end_tag(); } -fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml::Serializer, id: node_id) { ebml_w.start_tag(tag_items_data_item_symbol); ebml_w.writer.write(str::to_bytes(ecx.discrim_symbols.get(id))); ebml_w.end_tag(); } -fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml::Serializer, disr_val: int) { ebml_w.start_tag(tag_disr_val); ebml_w.writer.write(str::to_bytes(int::to_str(disr_val,10u))); ebml_w.end_tag(); } -fn encode_parent_item(ebml_w: ebml2::Serializer, id: def_id) { +fn encode_parent_item(ebml_w: ebml::Serializer, id: def_id) { ebml_w.start_tag(tag_items_data_parent_item); ebml_w.writer.write(str::to_bytes(def_to_str(id))); ebml_w.end_tag(); } -fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::Serializer, id: node_id, variants: ~[variant], path: ast_map::path, index: @mut ~[entry], ty_params: ~[ty_param]) { @@ -269,9 +269,9 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, } } -fn encode_path(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_path(ecx: @encode_ctxt, ebml_w: ebml::Serializer, path: ast_map::path, name: ast_map::path_elt) { - fn encode_path_elt(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, + fn encode_path_elt(ecx: @encode_ctxt, ebml_w: ebml::Serializer, elt: ast_map::path_elt) { let (tag, name) = match elt { ast_map::path_mod(name) => (tag_path_elt_mod, name), @@ -290,7 +290,7 @@ fn encode_path(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, } } -fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, md: _mod, +fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::Serializer, md: _mod, id: node_id, path: ast_map::path, name: ident) { ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(id)); @@ -348,7 +348,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, md: _mod, ebml_w.end_tag(); } -fn encode_visibility(ebml_w: ebml2::Serializer, visibility: visibility) { +fn encode_visibility(ebml_w: ebml::Serializer, visibility: visibility) { encode_family(ebml_w, match visibility { public => 'g', private => 'j', @@ -356,7 +356,7 @@ fn encode_visibility(ebml_w: ebml2::Serializer, visibility: visibility) { }); } -fn encode_self_type(ebml_w: ebml2::Serializer, self_type: ast::self_ty_) { +fn encode_self_type(ebml_w: ebml::Serializer, self_type: ast::self_ty_) { ebml_w.start_tag(tag_item_trait_method_self_ty); // Encode the base self type. @@ -389,7 +389,7 @@ fn encode_self_type(ebml_w: ebml2::Serializer, self_type: ast::self_ty_) { } /* Returns an index of items in this class */ -fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::Serializer, id: node_id, path: ast_map::path, class_tps: ~[ty_param], fields: ~[@struct_field], @@ -445,7 +445,7 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, } // This is for encoding info for ctors and dtors -fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml::Serializer, id: node_id, ident: ident, path: ast_map::path, item: Option, tps: ~[ty_param]) { ebml_w.start_tag(tag_items_data_item); @@ -470,7 +470,7 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, ebml_w.end_tag(); } -fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::Serializer, impl_path: ast_map::path, should_inline: bool, parent_id: node_id, m: @method, all_tps: ~[ty_param]) { @@ -520,7 +520,7 @@ fn should_inline(attrs: ~[attribute]) -> bool { } -fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Serializer, item: @item, index: @mut ~[entry], path: ast_map::path) { @@ -533,7 +533,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, }; if !must_write && !reachable(ecx, item.id) { return; } - fn add_to_index_(item: @item, ebml_w: ebml2::Serializer, + fn add_to_index_(item: @item, ebml_w: ebml::Serializer, index: @mut ~[entry]) { index.push({val: item.id, pos: ebml_w.writer.tell()}); } @@ -810,7 +810,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, } } -fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::Serializer, nitem: @foreign_item, index: @mut ~[entry], path: ast_map::path, abi: foreign_abi) { @@ -843,7 +843,7 @@ fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, ebml_w.end_tag(); } -fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::Serializer, crate: @crate) -> ~[entry] { let index = @mut ~[]; ebml_w.start_tag(tag_items_data); @@ -898,7 +898,7 @@ fn create_index(index: ~[entry]) -> return buckets_frozen; } -fn encode_index(ebml_w: ebml2::Serializer, buckets: ~[@~[entry]], +fn encode_index(ebml_w: ebml::Serializer, buckets: ~[@~[entry]], write_fn: fn(io::Writer, T)) { let writer = ebml_w.writer; ebml_w.start_tag(tag_index); @@ -933,7 +933,7 @@ fn write_int(writer: io::Writer, &&n: int) { writer.write_be_u32(n as u32); } -fn encode_meta_item(ebml_w: ebml2::Serializer, mi: meta_item) { +fn encode_meta_item(ebml_w: ebml::Serializer, mi: meta_item) { match mi.node { meta_word(name) => { ebml_w.start_tag(tag_meta_item_word); @@ -970,7 +970,7 @@ fn encode_meta_item(ebml_w: ebml2::Serializer, mi: meta_item) { } } -fn encode_attributes(ebml_w: ebml2::Serializer, attrs: ~[attribute]) { +fn encode_attributes(ebml_w: ebml::Serializer, attrs: ~[attribute]) { ebml_w.start_tag(tag_attributes); for attrs.each |attr| { ebml_w.start_tag(tag_attribute); @@ -1031,7 +1031,7 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] { return attrs; } -fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml::Serializer, cstore: cstore::cstore) { fn get_ordered_deps(ecx: @encode_ctxt, cstore: cstore::cstore) @@ -1077,7 +1077,7 @@ fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, ebml_w.end_tag(); } -fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, +fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml::Serializer, dep: decoder::crate_dep) { ebml_w.start_tag(tag_crate_dep); ebml_w.start_tag(tag_crate_dep_name); @@ -1092,7 +1092,7 @@ fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml2::Serializer, ebml_w.end_tag(); } -fn encode_hash(ebml_w: ebml2::Serializer, hash: ~str) { +fn encode_hash(ebml_w: ebml::Serializer, hash: ~str) { ebml_w.start_tag(tag_crate_hash); ebml_w.writer.write(str::to_bytes(hash)); ebml_w.end_tag(); @@ -1130,7 +1130,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { type_abbrevs: ty::new_ty_hash() }); - let ebml_w = ebml2::Serializer(wr as io::Writer); + let ebml_w = ebml::Serializer(wr as io::Writer); encode_hash(ebml_w, ecx.link_meta.extras_hash); diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index 39ec58c079e..103f1eecf87 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -7,15 +7,14 @@ use syntax::visit; use syntax::ast_map; use syntax::ast_util; use syntax::codemap::span; -use std::ebml2; -use std::ebml2::Serializer; -use std::ebml2::get_doc; +use std::ebml; +use std::ebml::{Serializer, get_doc}; use std::map::HashMap; -use std::serialization2; -use std::serialization2::{Serializable, - SerializerHelpers, - DeserializerHelpers, - deserialize}; +use std::serialization; +use std::serialization::{Serializable, + SerializerHelpers, + DeserializerHelpers, + deserialize}; use middle::{ty, typeck}; use middle::typeck::{method_origin, method_map_entry, vtable_res, @@ -74,7 +73,7 @@ trait tr { // Top-level methods. fn encode_inlined_item(ecx: @e::encode_ctxt, - ebml_w: ebml2::Serializer, + ebml_w: ebml::Serializer, path: ast_map::path, ii: ast::inlined_item, maps: maps) { @@ -100,14 +99,14 @@ fn decode_inlined_item(cdata: cstore::crate_metadata, tcx: ty::ctxt, maps: maps, path: ast_map::path, - par_doc: ebml2::Doc) -> Option { + par_doc: ebml::Doc) -> Option { let dcx = @{cdata: cdata, tcx: tcx, maps: maps}; match par_doc.opt_child(c::tag_ast) { None => None, Some(ast_doc) => { debug!("> Decoding inlined fn: %s::?", ast_map::path_to_str(path, tcx.sess.parse_sess.interner)); - let ast_dsr = &ebml2::Deserializer(ast_doc); + let ast_dsr = &ebml::Deserializer(ast_doc); let from_id_range = deserialize(ast_dsr); let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range); let xcx = extended_decode_ctxt_(@{dcx: dcx, @@ -185,7 +184,7 @@ trait def_id_serializer_helpers { fn emit_def_id(did: ast::def_id); } -impl S: def_id_serializer_helpers { +impl S: def_id_serializer_helpers { fn emit_def_id(did: ast::def_id) { did.serialize(&self) } @@ -195,7 +194,7 @@ trait def_id_deserializer_helpers { fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id; } -impl D: def_id_deserializer_helpers { +impl D: def_id_deserializer_helpers { fn read_def_id(xcx: extended_decode_ctxt) -> ast::def_id { let did: ast::def_id = deserialize(&self); @@ -218,7 +217,7 @@ impl D: def_id_deserializer_helpers { // We also have to adjust the spans: for now we just insert a dummy span, // but eventually we should add entries to the local codemap as required. -fn encode_ast(ebml_w: ebml2::Serializer, item: ast::inlined_item) { +fn encode_ast(ebml_w: ebml::Serializer, item: ast::inlined_item) { do ebml_w.wr_tag(c::tag_tree as uint) { item.serialize(&ebml_w) } @@ -278,9 +277,9 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item { } } -fn decode_ast(par_doc: ebml2::Doc) -> ast::inlined_item { +fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item { let chi_doc = par_doc[c::tag_tree as uint]; - let d = &ebml2::Deserializer(chi_doc); + let d = &ebml::Deserializer(chi_doc); deserialize(d) } @@ -332,12 +331,12 @@ fn renumber_ast(xcx: extended_decode_ctxt, ii: ast::inlined_item) // ______________________________________________________________________ // Encoding and decoding of ast::def -fn encode_def(ebml_w: ebml2::Serializer, def: ast::def) { +fn encode_def(ebml_w: ebml::Serializer, def: ast::def) { def.serialize(&ebml_w) } -fn decode_def(xcx: extended_decode_ctxt, doc: ebml2::Doc) -> ast::def { - let dsr = &ebml2::Deserializer(doc); +fn decode_def(xcx: extended_decode_ctxt, doc: ebml::Doc) -> ast::def { + let dsr = &ebml::Deserializer(doc); let def: ast::def = deserialize(dsr); def.tr(xcx) } @@ -423,7 +422,7 @@ impl ty::bound_region: tr { // ______________________________________________________________________ // Encoding and decoding of freevar information -fn encode_freevar_entry(ebml_w: ebml2::Serializer, fv: @freevar_entry) { +fn encode_freevar_entry(ebml_w: ebml::Serializer, fv: @freevar_entry) { (*fv).serialize(&ebml_w) } @@ -431,7 +430,7 @@ trait ebml_deserializer_helper { fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry; } -impl ebml2::Deserializer: ebml_deserializer_helper { +impl ebml::Deserializer: ebml_deserializer_helper { fn read_freevar_entry(xcx: extended_decode_ctxt) -> freevar_entry { let fv: freevar_entry = deserialize(&self); fv.tr(xcx) @@ -452,7 +451,7 @@ trait read_method_map_entry_helper { } fn serialize_method_map_entry(ecx: @e::encode_ctxt, - ebml_w: ebml2::Serializer, + ebml_w: ebml::Serializer, mme: method_map_entry) { do ebml_w.emit_rec { do ebml_w.emit_field(~"self_arg", 0u) { @@ -464,7 +463,7 @@ fn serialize_method_map_entry(ecx: @e::encode_ctxt, } } -impl ebml2::Deserializer: read_method_map_entry_helper { +impl ebml::Deserializer: read_method_map_entry_helper { fn read_method_map_entry(xcx: extended_decode_ctxt) -> method_map_entry { do self.read_rec { {self_arg: @@ -503,7 +502,7 @@ impl method_origin: tr { // Encoding and decoding vtable_res fn encode_vtable_res(ecx: @e::encode_ctxt, - ebml_w: ebml2::Serializer, + ebml_w: ebml::Serializer, dr: typeck::vtable_res) { // can't autogenerate this code because automatic serialization of // ty::t doesn't work, and there is no way (atm) to have @@ -515,7 +514,7 @@ fn encode_vtable_res(ecx: @e::encode_ctxt, } fn encode_vtable_origin(ecx: @e::encode_ctxt, - ebml_w: ebml2::Serializer, + ebml_w: ebml::Serializer, vtable_origin: typeck::vtable_origin) { do ebml_w.emit_enum(~"vtable_origin") { match vtable_origin { @@ -562,7 +561,7 @@ trait vtable_deserialization_helpers { fn read_vtable_origin(xcx: extended_decode_ctxt) -> typeck::vtable_origin; } -impl ebml2::Deserializer: vtable_deserialization_helpers { +impl ebml::Deserializer: vtable_deserialization_helpers { fn read_vtable_res(xcx: extended_decode_ctxt) -> typeck::vtable_res { @self.read_to_vec(|| self.read_vtable_origin(xcx) ) } @@ -639,7 +638,7 @@ trait ebml_writer_helpers { fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty); } -impl ebml2::Serializer: ebml_writer_helpers { +impl ebml::Serializer: ebml_writer_helpers { fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t) { do self.emit_opaque { e::write_type(ecx, self, ty) @@ -692,7 +691,7 @@ trait write_tag_and_id { fn id(id: ast::node_id); } -impl ebml2::Serializer: write_tag_and_id { +impl ebml::Serializer: write_tag_and_id { fn tag(tag_id: c::astencode_tag, f: fn()) { do self.wr_tag(tag_id as uint) { f() } } @@ -704,7 +703,7 @@ impl ebml2::Serializer: write_tag_and_id { fn encode_side_tables_for_ii(ecx: @e::encode_ctxt, maps: maps, - ebml_w: ebml2::Serializer, + ebml_w: ebml::Serializer, ii: ast::inlined_item) { do ebml_w.wr_tag(c::tag_table as uint) { ast_util::visit_ids_for_inlined_item( @@ -720,7 +719,7 @@ fn encode_side_tables_for_ii(ecx: @e::encode_ctxt, fn encode_side_tables_for_id(ecx: @e::encode_ctxt, maps: maps, - ebml_w: ebml2::Serializer, + ebml_w: ebml::Serializer, id: ast::node_id) { let tcx = ecx.tcx; @@ -849,13 +848,13 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, trait doc_decoder_helpers { fn as_int() -> int; - fn opt_child(tag: c::astencode_tag) -> Option; + fn opt_child(tag: c::astencode_tag) -> Option; } -impl ebml2::Doc: doc_decoder_helpers { - fn as_int() -> int { ebml2::doc_as_u64(self) as int } - fn opt_child(tag: c::astencode_tag) -> Option { - ebml2::maybe_get_doc(self, tag as uint) +impl ebml::Doc: doc_decoder_helpers { + fn as_int() -> int { ebml::doc_as_u64(self) as int } + fn opt_child(tag: c::astencode_tag) -> Option { + ebml::maybe_get_doc(self, tag as uint) } } @@ -868,7 +867,7 @@ trait ebml_deserializer_decoder_helpers { -> ty::ty_param_bounds_and_ty; } -impl ebml2::Deserializer: ebml_deserializer_decoder_helpers { +impl ebml::Deserializer: ebml_deserializer_decoder_helpers { fn read_arg(xcx: extended_decode_ctxt) -> ty::arg { do self.read_opaque |doc| { @@ -923,10 +922,10 @@ impl ebml2::Deserializer: ebml_deserializer_decoder_helpers { } fn decode_side_tables(xcx: extended_decode_ctxt, - ast_doc: ebml2::Doc) { + ast_doc: ebml::Doc) { let dcx = xcx.dcx; let tbl_doc = ast_doc[c::tag_table as uint]; - for ebml2::docs(tbl_doc) |tag, entry_doc| { + for ebml::docs(tbl_doc) |tag, entry_doc| { let id0 = entry_doc[c::tag_table_id as uint].as_int(); let id = xcx.tr_id(id0); @@ -940,7 +939,7 @@ fn decode_side_tables(xcx: extended_decode_ctxt, dcx.tcx.legacy_boxed_traits.insert(id, ()); } else { let val_doc = entry_doc[c::tag_table_val as uint]; - let val_dsr = &ebml2::Deserializer(val_doc); + let val_dsr = &ebml::Deserializer(val_doc); if tag == (c::tag_table_def as uint) { let def = decode_def(xcx, val_doc); dcx.tcx.def_map.insert(id, def); @@ -993,16 +992,16 @@ fn decode_side_tables(xcx: extended_decode_ctxt, // Testing of astencode_gen #[cfg(test)] -fn encode_item_ast(ebml_w: ebml2::Serializer, item: @ast::item) { +fn encode_item_ast(ebml_w: ebml::Serializer, item: @ast::item) { do ebml_w.wr_tag(c::tag_tree as uint) { (*item).serialize(&ebml_w) } } #[cfg(test)] -fn decode_item_ast(par_doc: ebml2::Doc) -> @ast::item { +fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item { let chi_doc = par_doc[c::tag_tree as uint]; - let d = &ebml2::Deserializer(chi_doc); + let d = &ebml::Deserializer(chi_doc); @deserialize(d) } @@ -1029,17 +1028,17 @@ fn mk_ctxt() -> fake_ext_ctxt { #[cfg(test)] fn roundtrip(in_item: @ast::item) { let bytes = do io::with_bytes_writer |wr| { - let ebml_w = ebml2::Serializer(wr); + let ebml_w = ebml::Serializer(wr); encode_item_ast(ebml_w, in_item); }; - let ebml_doc = ebml2::Doc(@bytes); + let ebml_doc = ebml::Doc(@bytes); let out_item = decode_item_ast(ebml_doc); let exp_str = do io::with_str_writer |w| { - in_item.serialize(&std::prettyprint2::Serializer(w)) + in_item.serialize(&std::prettyprint::Serializer(w)) }; let out_str = do io::with_str_writer |w| { - out_item.serialize(&std::prettyprint2::Serializer(w)) + out_item.serialize(&std::prettyprint::Serializer(w)) }; debug!("expected string: %s", exp_str); diff --git a/src/rustc/middle/freevars.rs b/src/rustc/middle/freevars.rs index d26b9566c97..1b42c9bb4b6 100644 --- a/src/rustc/middle/freevars.rs +++ b/src/rustc/middle/freevars.rs @@ -16,8 +16,8 @@ export has_freevars; // A vector of defs representing the free variables referred to in a function. // (The def_upvar will already have been stripped). -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type freevar_entry = { def: ast::def, //< The variable being accessed free. span: span //< First span where it is accessed (there can be multiple) diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index bbc3a06fb67..ca41be6f9d0 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -211,8 +211,8 @@ type method = {ident: ast::ident, type mt = {ty: t, mutbl: ast::mutability}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum vstore { vstore_fixed(uint), vstore_uniq, @@ -271,8 +271,8 @@ enum ast_ty_to_ty_cache_entry { type opt_region_variance = Option; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum region_variance { rv_covariant, rv_invariant, rv_contravariant } impl region_variance : cmp::Eq { @@ -289,23 +289,23 @@ impl region_variance : cmp::Eq { pure fn ne(other: ®ion_variance) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type AutoAdjustment = { autoderefs: uint, autoref: Option }; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type AutoRef = { kind: AutoRefKind, region: region, mutbl: ast::mutability }; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum AutoRefKind { /// Convert from @[]/~[] to &[] (or str) AutoSlice, @@ -509,8 +509,8 @@ impl param_ty : to_bytes::IterBytes { /// Representation of regions: -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum region { /// Bound regions are found (primarily) in function types. They indicate /// region parameters that have yet to be replaced with actual regions @@ -538,8 +538,8 @@ enum region { re_var(RegionVid) } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum bound_region { /// The self region for classes, impls (&T in a type defn or &self/T) br_self, @@ -669,8 +669,8 @@ enum param_bound { enum TyVid = uint; enum IntVid = uint; enum FnVid = uint; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum RegionVid = uint; enum InferTy { diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index c2bd7f26bad..7cb04bc0ea3 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -75,8 +75,8 @@ export method_static, method_param, method_trait, method_self; export vtable_static, vtable_param, vtable_trait; export provided_methods_map; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum method_origin { // fully statically resolved method method_static(ast::def_id), @@ -93,8 +93,8 @@ enum method_origin { // details for a method invoked with a receiver whose type is a type parameter // with a bounded trait. -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type method_param = { // the trait containing the method to be invoked trait_id: ast::def_id, diff --git a/src/test/run-pass/auto_serialize2.rs b/src/test/run-pass/auto_serialize.rs similarity index 86% rename from src/test/run-pass/auto_serialize2.rs rename to src/test/run-pass/auto_serialize.rs index 4503ea6c7e0..6c85f59b74e 100644 --- a/src/test/run-pass/auto_serialize2.rs +++ b/src/test/run-pass/auto_serialize.rs @@ -4,10 +4,10 @@ extern mod std; // the common code. use cmp::Eq; -use std::ebml2; +use std::ebml; use io::Writer; -use std::serialization2::{Serializable, Deserializable, deserialize}; -use std::prettyprint2; +use std::serialization::{Serializable, Deserializable, deserialize}; +use std::prettyprint; fn test_ser_and_deser( a1: &A, @@ -15,23 +15,23 @@ fn test_ser_and_deser( ) { // check the pretty printer: let s = do io::with_str_writer |w| { - a1.serialize(&prettyprint2::Serializer(w)) + a1.serialize(&prettyprint::Serializer(w)) }; debug!("s == %?", s); assert s == expected; // check the EBML serializer: let bytes = do io::with_bytes_writer |wr| { - let ebml_w = &ebml2::Serializer(wr); + let ebml_w = &ebml::Serializer(wr); a1.serialize(ebml_w) }; - let d = ebml2::Doc(@bytes); - let a2: A = deserialize(&ebml2::Deserializer(d)); + let d = ebml::Doc(@bytes); + let a2: A = deserialize(&ebml::Deserializer(d)); assert *a1 == a2; } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum Expr { Val(uint), Plus(@Expr, @Expr), @@ -105,8 +105,8 @@ impl CLike : cmp::Eq { pure fn ne(other: &CLike) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type Spanned = {lo: uint, hi: uint, node: T}; impl Spanned : cmp::Eq { @@ -116,27 +116,27 @@ impl Spanned : cmp::Eq { pure fn ne(other: &Spanned) -> bool { !self.eq(other) } } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] type SomeRec = {v: ~[uint]}; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum AnEnum = SomeRec; -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] struct Point {x: uint, y: uint} -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum Quark { Top(T), Bottom(T) } -#[auto_serialize2] -#[auto_deserialize2] +#[auto_serialize] +#[auto_deserialize] enum CLike { A, B, C } fn main() {