Skip to content

Commit f02d0fe

Browse files
ericktnikomatsakis
authored andcommitted
---
yaml --- r: 33003 b: refs/heads/dist-snap c: c46b6f9 h: refs/heads/master i: 33001: 0ecbc0c 32999: 9c60041 v: v3
1 parent 8bea4aa commit f02d0fe

File tree

2 files changed

+107
-58
lines changed

2 files changed

+107
-58
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df
99
refs/heads/incoming: d9317a174e434d4c99fc1a37fd7dc0d2f5328d37
10-
refs/heads/dist-snap: 8fc3088b2aba397c0f561ce978b2d4a47f8a9eab
10+
refs/heads/dist-snap: c46b6f9efbbb00706a62d86a9afc4fd59bc13c12
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/dist-snap/src/libsyntax/ext/auto_serialize2.rs

Lines changed: 106 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,42 @@ companion module with the same name as the item.
77
88
For example, a type like:
99
10-
type node_id = uint;
10+
#[auto_serialize2]
11+
struct Node {id: uint}
1112
1213
would generate two implementations like:
1314
14-
impl node_id: Serializable {
15+
impl Node: Serializable {
1516
fn serialize<S: Serializer>(s: &S) {
16-
s.emit_uint(self)
17+
do s.emit_struct("Node") {
18+
s.emit_field("id", 0, || s.emit_uint(self))
19+
}
1720
}
1821
}
1922
2023
impl node_id: Deserializable {
21-
static fn deserialize<D: Deserializer>(d: &D) -> node_id {
22-
d.read_uint()
24+
static fn deserialize<D: Deserializer>(d: &D) -> Node {
25+
do d.read_struct("Node") {
26+
Node {
27+
id: d.read_field(~"x", 0, || deserialize(d))
28+
}
29+
}
2330
}
2431
}
2532
2633
Other interesting scenarios are whe the item has type parameters or
2734
references other non-built-in types. A type definition like:
2835
36+
#[auto_serialize2]
2937
type spanned<T> = {node: T, span: span};
3038
3139
would yield functions like:
3240
3341
impl<T: Serializable> spanned<T>: Serializable {
3442
fn serialize<S: Serializer>(s: &S) {
3543
do s.emit_rec {
36-
s.emit_field("node", 0, self.node.serialize(s));
37-
s.emit_field("span", 1, self.span.serialize(s));
44+
s.emit_field("node", 0, || self.node.serialize(s));
45+
s.emit_field("span", 1, || self.span.serialize(s));
3846
}
3947
}
4048
}
@@ -395,33 +403,38 @@ fn mk_rec_impl(
395403
fields: ~[ast::ty_field],
396404
tps: ~[ast::ty_param]
397405
) -> ~[@ast::item] {
398-
// Records and structs don't have the same fields types, but they share
399-
// enough that if we extract the right subfields out we can share the
400-
// serialization generator code.
401-
let fields = do fields.map |field| {
402-
{
403-
span: field.span,
404-
ident: field.node.ident,
405-
mutbl: field.node.mt.mutbl,
406-
}
407-
};
406+
let fields = mk_rec_fields(fields);
407+
let ser_fields = mk_ser_fields(cx, span, fields);
408+
let deser_fields = mk_deser_fields(cx, span, fields);
408409

409-
let ser_body = mk_ser_fields(cx, span, fields);
410-
411-
// ast for `__s.emit_rec($(ser_body))`
410+
// ast for `__s.emit_rec(|| $(ser_fields))`
412411
let ser_body = cx.expr_call(
413412
span,
414413
cx.expr_field(
415414
span,
416415
cx.expr_var(span, ~"__s"),
417416
cx.ident_of(~"emit_rec")
418417
),
419-
~[ser_body]
418+
~[cx.lambda_stmts(span, ser_fields)]
420419
);
421420

422-
let deser_body = do mk_deser_fields(cx, span, fields) |fields| {
423-
cx.expr(span, ast::expr_rec(fields, None))
424-
};
421+
// ast for `read_rec(|| $(deser_fields))`
422+
let deser_body = cx.expr_call(
423+
span,
424+
cx.expr_field(
425+
span,
426+
cx.expr_var(span, ~"__d"),
427+
cx.ident_of(~"read_rec")
428+
),
429+
~[
430+
cx.lambda_expr(
431+
cx.expr(
432+
span,
433+
ast::expr_rec(deser_fields, None)
434+
)
435+
)
436+
]
437+
);
425438

426439
~[
427440
mk_ser_impl(cx, span, ident, tps, ser_body),
@@ -436,55 +449,94 @@ fn mk_struct_impl(
436449
fields: ~[@ast::struct_field],
437450
tps: ~[ast::ty_param]
438451
) -> ~[@ast::item] {
439-
// Records and structs don't have the same fields types, but they share
440-
// enough that if we extract the right subfields out we can share the
441-
// serialization generator code.
442-
let fields = do fields.map |field| {
443-
let (ident, mutbl) = match field.node.kind {
444-
ast::named_field(ident, mutbl, _) => (ident, mutbl),
445-
_ => fail ~"[auto_serialize2] does not support \
446-
unnamed fields",
447-
};
448-
449-
{
450-
span: field.span,
451-
ident: ident,
452-
mutbl: match mutbl {
453-
ast::class_mutable => ast::m_mutbl,
454-
ast::class_immutable => ast::m_imm,
455-
},
456-
}
457-
};
452+
let fields = mk_struct_fields(fields);
453+
let ser_fields = mk_ser_fields(cx, span, fields);
454+
let deser_fields = mk_deser_fields(cx, span, fields);
458455

459-
let ser_body = mk_ser_fields(cx, span, fields);
460-
461-
// ast for `__s.emit_struct($(name), $(ser_body))`
456+
// ast for `__s.emit_struct($(name), || $(ser_fields))`
462457
let ser_body = cx.expr_call(
463458
span,
464459
cx.expr_field(
465460
span,
466461
cx.expr_var(span, ~"__s"),
467462
cx.ident_of(~"emit_struct")
468463
),
469-
~[cx.lit_str(span, @cx.str_of(ident)), ser_body]
464+
~[
465+
cx.lit_str(span, @cx.str_of(ident)),
466+
cx.lambda_stmts(span, ser_fields),
467+
]
470468
);
471469

472-
let deser_body = do mk_deser_fields(cx, span, fields) |fields| {
473-
cx.expr(span, ast::expr_struct(cx.path(span, ~[ident]), fields, None))
474-
};
470+
// ast for `read_struct($(name), || $(deser_fields))`
471+
let deser_body = cx.expr_call(
472+
span,
473+
cx.expr_field(
474+
span,
475+
cx.expr_var(span, ~"__d"),
476+
cx.ident_of(~"read_struct")
477+
),
478+
~[
479+
cx.lit_str(span, @cx.str_of(ident)),
480+
cx.lambda_expr(
481+
span,
482+
cx.expr(
483+
span,
484+
ast::expr_struct(
485+
cx.path(span, ~[ident]),
486+
deser_fields
487+
None
488+
)
489+
)
490+
),
491+
]
492+
)
475493

476494
~[
477495
mk_ser_impl(cx, span, ident, tps, ser_body),
478496
mk_deser_impl(cx, span, ident, tps, deser_body),
479497
]
480498
}
481499

500+
// Records and structs don't have the same fields types, but they share enough
501+
// that if we extract the right subfields out we can share the serialization
502+
// generator code.
503+
type field = { span: span, ident: ast::ident, mutbl: ast::mutability };
504+
505+
fn mk_rec_fields(fields: ~[ast::ty_field]) -> ~[field] {
506+
do fields.map |field| {
507+
{
508+
span: field.span,
509+
ident: field.node.ident,
510+
mutbl: field.node.mt.mutbl,
511+
}
512+
}
513+
}
514+
515+
fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] {
516+
do fields.map |field| {
517+
let (ident, mutbl) = match field.node.kind {
518+
ast::named_field(ident, mutbl, _) => (ident, mutbl),
519+
_ => fail ~"[auto_serialize2] does not support \
520+
unnamed fields",
521+
};
522+
523+
{
524+
span: field.span,
525+
ident: ident,
526+
mutbl: match mutbl {
527+
ast::class_mutable => ast::m_mutbl,
528+
ast::class_immutable => ast::m_imm,
529+
},
530+
}
531+
}
532+
}
533+
482534
fn mk_ser_fields(
483535
cx: ext_ctxt,
484536
span: span,
485-
fields: ~[{ span: span, ident: ast::ident, mutbl: ast::mutability }]
486-
) -> @ast::expr {
487-
let stmts = do fields.mapi |idx, field| {
537+
fields: ~[field]
538+
) -> ~[@ast::stmt] {
539+
do fields.mapi |idx, field| {
488540
// ast for `|| self.$(name).serialize(__s)`
489541
let expr_lambda = cx.lambda_expr(
490542
cx.expr_call(
@@ -518,10 +570,7 @@ fn mk_ser_fields(
518570
]
519571
)
520572
)
521-
};
522-
523-
// ast for `|| $(stmts)`
524-
cx.lambda_stmts(span, stmts)
573+
}
525574
}
526575

527576
fn mk_deser_fields(

0 commit comments

Comments
 (0)