diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-10-08 09:00:23 -0700 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-10-08 09:00:23 -0700 |
| commit | 7bdab1e4a45bf734e4b25a2d58f4ee21ee5c9fdc (patch) | |
| tree | b24c818211cffeb1f2b8cc7bf7bc31fe3eecfdc9 /src/libsyntax | |
| parent | 79603f573e504163db7b5c2afa0917c27e3f98ed (diff) | |
| download | rust-7bdab1e4a45bf734e4b25a2d58f4ee21ee5c9fdc.tar.gz rust-7bdab1e4a45bf734e4b25a2d58f4ee21ee5c9fdc.zip | |
Revert "remove ctor from ast"
This reverts commit ed3689d57c988e1dd477930d957c4308c37d1a64.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ast_map.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 19 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 65 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 33 |
7 files changed, 148 insertions, 23 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ced64daa8d6..1c279f81cc3 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -135,7 +135,7 @@ enum def { @def, // closed over def node_id, // expr node that creates the closure node_id), // id for the block/body of the closure expr - def_class(def_id), + def_class(def_id, bool /* has constructor */), def_typaram_binder(node_id), /* class, impl or trait that has ty params */ def_region(node_id), def_label(node_id) @@ -235,9 +235,9 @@ impl def : cmp::Eq { _ => false } } - def_class(e0a) => { + def_class(e0a, e1a) => { match (*other) { - def_class(e0b) => e0a == e0b, + def_class(e0b, e1b) => e0a == e0b && e1a == e1b, _ => false } } @@ -1462,6 +1462,8 @@ type struct_def = { fields: ~[@struct_field], /* fields */ methods: ~[@method], /* methods */ /* (not including ctor or dtor) */ + /* ctor is optional, and will soon go away */ + ctor: Option<class_ctor>, /* dtor is optional */ dtor: Option<class_dtor> }; @@ -1561,6 +1563,7 @@ enum inlined_item { ii_item(@item), ii_method(def_id /* impl id */, @method), ii_foreign(@foreign_item), + ii_ctor(class_ctor, ident, ~[ty_param], def_id /* parent id */), ii_dtor(class_dtor, ident, ~[ty_param], def_id /* parent id */) } diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 8555ceed2db..d05c6eadaf6 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -71,6 +71,9 @@ enum ast_node { // order they are introduced. node_arg(arg, uint), node_local(uint), + // Constructor for a class + // def_id is parent id + node_ctor(ident, ~[ty_param], @class_ctor, def_id, @path), // Destructor for a class node_dtor(~[ty_param], @class_dtor, def_id, @path), node_block(blk), @@ -129,7 +132,7 @@ fn map_decoded_item(diag: span_handler, // don't decode and instantiate the impl, but just the method, we have to // add it to the table now: match ii { - ii_item(*) | ii_dtor(*) => { /* fallthrough */ } + ii_item(*) | ii_ctor(*) | ii_dtor(*) => { /* fallthrough */ } ii_foreign(i) => { cx.map.insert(i.id, node_foreign_item(i, foreign_abi_rust_intrinsic, @path)); @@ -152,6 +155,18 @@ fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, cx.local_id += 1u; } match fk { + visit::fk_ctor(nm, attrs, tps, self_id, parent_id) => { + let ct = @{node: {id: id, + attrs: attrs, + self_id: self_id, + dec: /* FIXME (#2543) */ copy decl, + body: /* FIXME (#2543) */ copy body}, + span: sp}; + cx.map.insert(id, node_ctor(/* FIXME (#2543) */ copy nm, + /* FIXME (#2543) */ copy tps, + ct, parent_id, + @/* FIXME (#2543) */ copy cx.path)); + } visit::fk_dtor(tps, attrs, self_id, parent_id) => { let dt = @{node: {id: id, attrs: attrs, self_id: self_id, body: /* FIXME (#2543) */ copy body}, span: sp}; @@ -367,6 +382,9 @@ fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str { Some(node_local(_)) => { // add more info here fmt!("local (id=%?)", id) } + Some(node_ctor(*)) => { // add more info here + fmt!("node_ctor (id=%?)", id) + } Some(node_dtor(*)) => { // add more info here fmt!("node_dtor (id=%?)", id) } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 9e44c42a702..47cbdb7ac6c 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -57,7 +57,7 @@ pure fn def_id_of_def(d: def) -> def_id { def_fn(id, _) | def_static_method(id, _) | def_mod(id) | def_foreign_mod(id) | def_const(id) | def_variant(_, id) | def_ty(id) | def_ty_param(id, _) | - def_use(id) | def_class(id) => { + def_use(id) | def_class(id, _) => { id } def_arg(id, _) | def_local(id, _) | def_self(id) | @@ -339,6 +339,7 @@ impl inlined_item: inlined_item_utils { ii_item(i) => /* FIXME (#2543) */ copy i.ident, ii_foreign(i) => /* FIXME (#2543) */ copy i.ident, ii_method(_, m) => /* FIXME (#2543) */ copy m.ident, + ii_ctor(_, nm, _, _) => /* FIXME (#2543) */ copy nm, ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm } } @@ -348,6 +349,7 @@ impl inlined_item: inlined_item_utils { ii_item(i) => i.id, ii_foreign(i) => i.id, ii_method(_, m) => m.id, + ii_ctor(ctor, _, _, _) => ctor.node.id, ii_dtor(dtor, _, _, _) => dtor.node.id } } @@ -357,6 +359,9 @@ impl inlined_item: inlined_item_utils { ii_item(i) => v.visit_item(i, e, v), ii_foreign(i) => v.visit_foreign_item(i, e, v), ii_method(_, m) => visit::visit_method_helper(m, e, v), + ii_ctor(ctor, nm, tps, parent_id) => { + visit::visit_class_ctor_helper(ctor, nm, tps, parent_id, e, v); + } ii_dtor(dtor, _, tps, parent_id) => { visit::visit_class_dtor_helper(dtor, tps, parent_id, e, v); } @@ -490,6 +495,12 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { vfn(id); match fk { + visit::fk_ctor(_, _, tps, self_id, parent_id) => { + for vec::each(tps) |tp| { vfn(tp.id); } + vfn(id); + vfn(self_id); + vfn(parent_id.node); + } visit::fk_dtor(tps, _, self_id, parent_id) => { for vec::each(tps) |tp| { vfn(tp.id); } vfn(id); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 68d9cd80430..088df01985e 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -271,6 +271,23 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold) -> @ast::struct_def { + let resulting_optional_constructor; + match struct_def.ctor { + None => { + resulting_optional_constructor = None; + } + Some(constructor) => { + resulting_optional_constructor = Some({ + node: { + body: fld.fold_block(constructor.node.body), + dec: fold_fn_decl(constructor.node.dec, fld), + id: fld.new_id(constructor.node.id), + .. constructor.node + }, + .. constructor + }); + } + } let dtor = do option::map(&struct_def.dtor) |dtor| { let dtor_body = fld.fold_block(dtor.node.body); let dtor_id = fld.new_id(dtor.node.id); @@ -281,6 +298,7 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold) traits: vec::map(struct_def.traits, |p| fold_trait_ref(*p, fld)), fields: vec::map(struct_def.fields, |f| fold_struct_field(*f, fld)), methods: vec::map(struct_def.methods, |m| fld.fold_method(*m)), + ctor: resulting_optional_constructor, dtor: dtor }; } @@ -567,6 +585,7 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { |f| fld.fold_struct_field(*f)), methods: vec::map(struct_def.methods, |m| fld.fold_method(*m)), + ctor: None, dtor: dtor }) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f2e17c0a7e6..22c25186c91 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -115,7 +115,8 @@ enum class_member { So that we can distinguish a class ctor or dtor from other class members */ -enum class_contents { dtor_decl(blk, ~[attribute], codemap::span), +enum class_contents { ctor_decl(fn_decl, ~[attribute], blk, codemap::span), + dtor_decl(blk, ~[attribute], codemap::span), members(~[@class_member]) } type arg_or_capture_item = Either<arg, capture_item>; @@ -2682,13 +2683,30 @@ impl parser { let mut fields: ~[@struct_field]; let mut methods: ~[@method] = ~[]; + let mut the_ctor: Option<(fn_decl, ~[attribute], blk, codemap::span)> + = None; let mut the_dtor: Option<(blk, ~[attribute], codemap::span)> = None; + let ctor_id = self.get_id(); if self.eat(token::LBRACE) { // It's a record-like struct. fields = ~[]; while self.token != token::RBRACE { match self.parse_class_item() { + ctor_decl(a_fn_decl, attrs, blk, s) => { + match the_ctor { + Some((_, _, _, s_first)) => { + self.span_note(s, #fmt("Duplicate constructor \ + declaration for class %s", + *self.interner.get(class_name))); + self.span_fatal(copy s_first, ~"First constructor \ + declared here"); + } + None => { + the_ctor = Some((a_fn_decl, attrs, blk, s)); + } + } + } dtor_decl(blk, attrs, s) => { match the_dtor { Some((_, _, s_first)) => { @@ -2746,14 +2764,36 @@ impl parser { self_id: self.get_id(), body: d_body}, span: d_s}}; - (class_name, - item_class(@{ - traits: traits, - fields: move fields, - methods: move methods, - dtor: actual_dtor - }, ty_params), - None) + match the_ctor { + Some((ct_d, ct_attrs, ct_b, ct_s)) => { + (class_name, + item_class(@{ + traits: traits, + fields: move fields, + methods: move methods, + ctor: Some({ + node: {id: ctor_id, + attrs: ct_attrs, + self_id: self.get_id(), + dec: ct_d, + body: ct_b}, + span: ct_s}), + dtor: actual_dtor + }, ty_params), + None) + } + None => { + (class_name, + item_class(@{ + traits: traits, + fields: move fields, + methods: move methods, + ctor: None, + dtor: actual_dtor + }, ty_params), + None) + } + } } fn token_is_pound_or_doc_comment(++tok: token::token) -> bool { @@ -3057,6 +3097,12 @@ impl parser { let mut methods: ~[@method] = ~[]; while self.token != token::RBRACE { match self.parse_class_item() { + ctor_decl(*) => { + self.span_fatal(copy self.span, + ~"deprecated explicit \ + constructors are not allowed \ + here"); + } dtor_decl(blk, attrs, s) => { match the_dtor { Some((_, _, s_first)) => { @@ -3097,6 +3143,7 @@ impl parser { traits: ~[], fields: move fields, methods: move methods, + ctor: None, dtor: actual_dtor }; } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b98014f421b..bff356e5cb7 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -653,6 +653,18 @@ fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param], } bopen(s); hardbreak_if_not_bol(s); + do struct_def.ctor.iter |ctor| { + maybe_print_comment(s, ctor.span.lo); + print_outer_attributes(s, ctor.node.attrs); + // Doesn't call head because there shouldn't be a space after new. + cbox(s, indent_unit); + ibox(s, 4); + word(s.s, ~"new("); + print_fn_args(s, ctor.node.dec, ~[], None); + word(s.s, ~")"); + space(s.s); + print_block(s, ctor.node.body); + } do struct_def.dtor.iter |dtor| { hardbreak_if_not_bol(s); maybe_print_comment(s, dtor.span.lo); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 50fbd21f7b8..e6fd65eb458 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -17,6 +17,8 @@ enum fn_kind { fk_method(ident, ~[ty_param], @method), fk_anon(proto, capture_clause), //< an anonymous function like fn@(...) fk_fn_block(capture_clause), //< a block {||...} + fk_ctor(ident, ~[attribute], ~[ty_param], node_id /* self id */, + def_id /* parent class id */), // class constructor fk_dtor(~[ty_param], ~[attribute], node_id /* self id */, def_id /* parent class id */) // class destructor @@ -24,9 +26,8 @@ enum fn_kind { fn name_of_fn(fk: fn_kind) -> ident { match fk { - fk_item_fn(name, _, _) | fk_method(name, _, _) => { - /* FIXME (#2543) */ copy name - } + fk_item_fn(name, _, _) | fk_method(name, _, _) + | fk_ctor(name, _, _, _, _) => /* FIXME (#2543) */ copy name, fk_anon(*) | fk_fn_block(*) => parse::token::special_idents::anon, fk_dtor(*) => parse::token::special_idents::dtor } @@ -34,11 +35,11 @@ fn name_of_fn(fk: fn_kind) -> ident { fn tps_of_fn(fk: fn_kind) -> ~[ty_param] { match fk { - fk_item_fn(_, tps, _) | fk_method(_, tps, _) | - fk_dtor(tps, _, _, _) => { - /* FIXME (#2543) */ copy tps - } - fk_anon(*) | fk_fn_block(*) => ~[] + fk_item_fn(_, tps, _) | fk_method(_, tps, _) + | fk_ctor(_, _, tps, _, _) | fk_dtor(tps, _, _, _) => { + /* FIXME (#2543) */ copy tps + } + fk_anon(*) | fk_fn_block(*) => ~[] } } @@ -290,6 +291,17 @@ fn visit_method_helper<E>(m: @method, e: E, v: vt<E>) { m.decl, m.body, m.span, m.id, e, v); } +// Similar logic to the comment on visit_method_helper - Tim +fn visit_class_ctor_helper<E>(ctor: class_ctor, nm: ident, tps: ~[ty_param], + parent_id: def_id, e: E, v: vt<E>) { + v.visit_fn(fk_ctor(/* FIXME (#2543) */ copy nm, + ctor.node.attrs, + /* FIXME (#2543) */ copy tps, + ctor.node.self_id, parent_id), + ctor.node.dec, ctor.node.body, ctor.span, ctor.node.id, e, v) + +} + fn visit_class_dtor_helper<E>(dtor: class_dtor, tps: ~[ty_param], parent_id: def_id, e: E, v: vt<E>) { v.visit_fn(fk_dtor(/* FIXME (#2543) */ copy tps, dtor.node.attrs, @@ -318,7 +330,7 @@ fn visit_trait_method<E>(m: trait_method, e: E, v: vt<E>) { } } -fn visit_struct_def<E>(sd: @struct_def, _nm: ast::ident, tps: ~[ty_param], +fn visit_struct_def<E>(sd: @struct_def, nm: ast::ident, tps: ~[ty_param], id: node_id, e: E, v: vt<E>) { for sd.fields.each |f| { v.visit_struct_field(*f, e, v); @@ -329,6 +341,9 @@ fn visit_struct_def<E>(sd: @struct_def, _nm: ast::ident, tps: ~[ty_param], for sd.traits.each |p| { visit_path(p.path, e, v); } + do option::iter(&sd.ctor) |ctor| { + visit_class_ctor_helper(*ctor, nm, tps, ast_util::local_def(id), e, v); + }; do option::iter(&sd.dtor) |dtor| { visit_class_dtor_helper(*dtor, tps, ast_util::local_def(id), e, v) }; |
