diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-11-30 11:18:25 -0800 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-11-30 20:41:46 -0800 |
| commit | f34833abfce74cf178c0589a4b7cf5fba9d2a2db (patch) | |
| tree | 08943a296d704c10303fbd6b33b3d7e8fb704ac6 /src/libsyntax | |
| parent | 54ae377ec26ed47bbb627bdcb58bb10658cf03c4 (diff) | |
| download | rust-f34833abfce74cf178c0589a4b7cf5fba9d2a2db.tar.gz rust-f34833abfce74cf178c0589a4b7cf5fba9d2a2db.zip | |
librustc: Make `a.b()` always a method call. r=nmatsakis
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/parse/classify.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 48 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 89 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 5 |
6 files changed, 121 insertions, 41 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1ffe741d255..9dab40ba991 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -645,7 +645,7 @@ impl blk_check_mode : cmp::Eq { #[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 +// Extra node ID is only used for index, assign_op, unary, binary, method call #[auto_serialize] #[auto_deserialize] @@ -659,6 +659,7 @@ enum expr_ { expr_vec(~[@expr], mutability), expr_rec(~[field], Option<@expr>), expr_call(@expr, ~[@expr], bool), // True iff last argument is a block + expr_method_call(@expr, ident, ~[@Ty], ~[@expr], bool), // Ditto expr_tup(~[@expr]), expr_binary(binop, @expr, @expr), expr_unary(unop, @expr), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 9a1f3e7f04e..03a9729477a 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -409,6 +409,13 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { fld.map_exprs(|x| fld.fold_expr(x), args), blk) } + expr_method_call(f, i, tps, args, blk) => { + expr_method_call(fld.fold_expr(f), + fld.fold_ident(i), + vec::map(tps, |x| fld.fold_ty(*x)), + fld.map_exprs(|x| fld.fold_expr(x), args), + blk) + } expr_binary(binop, lhs, rhs) => { expr_binary(binop, fld.fold_expr(lhs), fld.fold_expr(rhs)) } diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 0d370525d17..e0210feb9de 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -6,9 +6,13 @@ use ast_util::operator_prec; fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { match e.node { - ast::expr_if(*) | ast::expr_match(*) | ast::expr_block(_) - | ast::expr_while(*) | ast::expr_loop(*) - | ast::expr_call(_, _, true) => false, + ast::expr_if(*) + | ast::expr_match(*) + | ast::expr_block(_) + | ast::expr_while(*) + | ast::expr_loop(*) + | ast::expr_call(_, _, true) + | ast::expr_method_call(_, _, _, _, true) => false, _ => true } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d8fd58b3d50..7cf279d0d81 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -34,10 +34,10 @@ use ast::{_mod, add, arg, arm, attribute, expr_call, expr_cast, expr_copy, expr_do_body, expr_fail, expr_field, expr_fn, expr_fn_block, expr_if, expr_index, expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac, - expr_paren, expr_path, expr_rec, expr_repeat, expr_ret, - expr_swap, expr_struct, expr_tup, expr_unary, expr_unary_move, - expr_vec, expr_vstore, expr_vstore_mut_box, expr_while, - extern_fn, field, fn_decl, + expr_method_call, expr_paren, expr_path, expr_rec, expr_repeat, + expr_ret, expr_swap, expr_struct, expr_tup, expr_unary, + expr_unary_move, expr_vec, expr_vstore, expr_vstore_mut_box, + expr_while, extern_fn, field, fn_decl, foreign_item, foreign_item_const, foreign_item_fn, foreign_mod, ident, impure_fn, infer, inherited, item, item_, item_class, item_const, item_enum, item_fn, @@ -1212,8 +1212,26 @@ impl Parser { self.expect(token::LT); self.parse_seq_to_gt(Some(token::COMMA), |p| p.parse_ty(false)) - } else { ~[] }; - e = self.mk_expr(lo, hi, expr_field(e, i, tys)); + } else { + ~[] + }; + + // expr.f() method call + match copy self.token { + token::LPAREN if self.permits_call() => { + let es = self.parse_unspanned_seq( + token::LPAREN, token::RPAREN, + seq_sep_trailing_disallowed(token::COMMA), + |p| p.parse_expr()); + hi = self.span.hi; + + let nd = expr_method_call(e, i, tys, es, false); + e = self.mk_expr(lo, hi, move nd); + } + _ => { + e = self.mk_expr(lo, hi, expr_field(e, i, tys)); + } + } } _ => self.unexpected() } @@ -1674,7 +1692,23 @@ impl Parser { @{node: expr_call(f, args, true), .. *e} } - expr_path(*) | expr_field(*) | expr_call(*) | expr_paren(*) => { + expr_method_call(f, i, tps, args, false) => { + let block = self.parse_lambda_block_expr(); + let last_arg = self.mk_expr(block.span.lo, block.span.hi, + ctor(block)); + let args = vec::append(args, ~[last_arg]); + @{node: expr_method_call(f, i, tps, args, true), + .. *e} + } + expr_field(f, i, tps) => { + let block = self.parse_lambda_block_expr(); + let last_arg = self.mk_expr(block.span.lo, block.span.hi, + ctor(block)); + @{node: expr_method_call(f, i, tps, ~[last_arg], true), + .. *e} + } + expr_path(*) | expr_call(*) | expr_method_call(*) | + expr_paren(*) => { let block = self.parse_lambda_block_expr(); let last_arg = self.mk_expr(block.span.lo, block.span.hi, ctor(block)); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5ad3c051c59..e13c6da403f 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1041,6 +1041,50 @@ fn print_expr_vstore(s: ps, t: ast::expr_vstore) { } } +fn print_call_pre(s: ps, + has_block: bool, + base_args: &mut ~[@ast::expr]) + -> Option<@ast::expr> { + if has_block { + let blk_arg = base_args.pop(); + match blk_arg.node { + ast::expr_loop_body(_) => { head(s, ~"for"); } + ast::expr_do_body(_) => { head(s, ~"do"); } + _ => {} + } + Some(blk_arg) + } else { + None + } +} + +fn print_call_post(s: ps, + has_block: bool, + blk: &Option<@ast::expr>, + base_args: &mut ~[@ast::expr]) { + if !has_block || base_args.is_not_empty() { + popen(s); + commasep_exprs(s, inconsistent, *base_args); + pclose(s); + } + if has_block { + nbsp(s); + match blk.get().node { + // need to handle closures specifically + ast::expr_do_body(e) | ast::expr_loop_body(e) => { + end(s); // we close our head box; closure + // will create it's own. + print_expr(s, e); + end(s); // close outer box, as closures don't + } + _ => { + // not sure if this can happen. + print_expr(s, blk.get()); + } + } + } +} + fn print_expr(s: ps, &&expr: @ast::expr) { fn print_field(s: ps, field: ast::field) { ibox(s, indent_unit); @@ -1135,38 +1179,23 @@ fn print_expr(s: ps, &&expr: @ast::expr) { pclose(s); } ast::expr_call(func, args, has_block) => { - let mut base_args = args; - let blk = if has_block { - let blk_arg = base_args.pop(); - match blk_arg.node { - ast::expr_loop_body(_) => { head(s, ~"for"); } - ast::expr_do_body(_) => { head(s, ~"do"); } - _ => {} - } - Some(blk_arg) - } else { None }; + let mut base_args = copy args; + let blk = print_call_pre(s, has_block, &mut base_args); print_expr(s, func); - if !has_block || base_args.is_not_empty() { - popen(s); - commasep_exprs(s, inconsistent, base_args); - pclose(s); - } - if has_block { - nbsp(s); - match blk.get().node { - // need to handle closures specifically - ast::expr_do_body(e) | ast::expr_loop_body(e) => { - end(s); // we close our head box; closure - // will create it's own. - print_expr(s, e); - end(s); // close outer box, as closures don't - } - _ => { - // not sure if this can happen. - print_expr(s, blk.get()); - } - } + print_call_post(s, has_block, &blk, &mut base_args); + } + ast::expr_method_call(func, ident, tys, args, has_block) => { + let mut base_args = copy args; + let blk = print_call_pre(s, has_block, &mut base_args); + print_expr(s, func); + word(s.s, ~"."); + print_ident(s, ident); + if vec::len(tys) > 0u { + word(s.s, ~"::<"); + commasep(s, inconsistent, tys, print_type); + word(s.s, ~">"); } + print_call_post(s, has_block, &blk, &mut base_args); } ast::expr_binary(op, lhs, rhs) => { print_expr(s, lhs); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index fbb1bc91172..bac651ef36c 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -408,6 +408,11 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) { visit_exprs(args, e, v); (v.visit_expr)(callee, e, v); } + expr_method_call(callee, _, tys, args, _) => { + visit_exprs(args, e, v); + for tys.each |tp| { (v.visit_ty)(*tp, e, v); } + (v.visit_expr)(callee, e, v); + } expr_binary(_, a, b) => { (v.visit_expr)(a, e, v); (v.visit_expr)(b, e, v); } |
