Allow explicit self-calls within classes

Allow writing self.f() within a class that has a method f. In a future
commit, this syntax will be required. For now, you can write either
self.f() or f().

I added a "privacy" field to all methods (whether class methods or not),
which allowed me to refactor the AST somewhat (getting rid of the
class_item type; now there's just class_member).
This commit is contained in:
Tim Chevalier
2012-03-28 18:50:33 -07:00
parent fe610f04d8
commit f7bbe537c1
18 changed files with 201 additions and 198 deletions

View File

@@ -1681,7 +1681,7 @@ fn parse_let(p: parser) -> @ast::decl {
}
/* assumes "let" token has already been consumed */
fn parse_instance_var(p:parser) -> (ast::class_member, codemap::span) {
fn parse_instance_var(p:parser, pr: ast::privacy) -> @ast::class_member {
let mut is_mutbl = ast::class_immutable;
let lo = p.span.lo;
if eat_word(p, "mut") || eat_word(p, "mutable") {
@@ -1693,8 +1693,8 @@ fn parse_instance_var(p:parser) -> (ast::class_member, codemap::span) {
let name = parse_ident(p);
expect(p, token::COLON);
let ty = parse_ty(p, false);
ret (ast::instance_var(name, ty, is_mutbl, p.get_id()),
ast_util::mk_sp(lo, p.last_span.hi));
ret @{node: ast::instance_var(name, ty, is_mutbl, p.get_id(), pr),
span: ast_util::mk_sp(lo, p.last_span.hi)};
}
fn parse_stmt(p: parser, first_item_attrs: [ast::attribute]) -> @ast::stmt {
@@ -1986,7 +1986,7 @@ fn parse_method_name(p: parser) -> ast::ident {
}
}
fn parse_method(p: parser) -> @ast::method {
fn parse_method(p: parser, pr: ast::privacy) -> @ast::method {
let attrs = parse_outer_attributes(p);
let lo = p.span.lo, pur = parse_fn_purity(p);
let ident = parse_method_name(p);
@@ -1996,7 +1996,7 @@ fn parse_method(p: parser) -> @ast::method {
let attrs = attrs + inner_attrs;
@{ident: ident, attrs: attrs, tps: tps, decl: decl, body: body,
id: p.get_id(), span: ast_util::mk_sp(lo, body.span.hi),
self_id: p.get_id()}
self_id: p.get_id(), privacy: pr}
}
fn parse_item_iface(p: parser, attrs: [ast::attribute]) -> @ast::item {
@@ -2034,7 +2034,7 @@ fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
let ty = parse_ty(p, false);
let mut meths = [];
expect(p, token::LBRACE);
while !eat(p, token::RBRACE) { meths += [parse_method(p)]; }
while !eat(p, token::RBRACE) { meths += [parse_method(p, ast::pub)]; }
ret mk_item(p, lo, p.last_span.hi, ident,
ast::item_impl(tps, ifce, ty, meths), attrs);
}
@@ -2070,24 +2070,15 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
let class_path = ident_to_path(p.last_span, class_name);
let ty_params = parse_ty_params(p);
expect(p, token::LBRACE);
let mut items: [@ast::class_item] = [];
let mut ms: [@ast::class_member] = [];
let ctor_id = p.get_id();
let mut the_ctor : option<(ast::fn_decl, ast::blk, codemap::span)> = none;
while p.token != token::RBRACE {
alt parse_class_item(p, class_path) {
ctor_decl(a_fn_decl, blk, s) {
ctor_decl(a_fn_decl, blk, s) {
the_ctor = some((a_fn_decl, blk, s));
}
plain_decl(a_decl, s) {
items += [@{node: {privacy: ast::pub, decl: a_decl},
span: s}];
}
priv_decls(some_decls) {
items += vec::map(some_decls, {|p|
let (d, s) = p;
@{node: {privacy: ast::priv, decl: d},
span: s}});
}
members(mms) { ms += mms; }
}
}
p.bump();
@@ -2095,7 +2086,7 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
some((ct_d, ct_b, ct_s)) {
ret mk_item(p, lo, p.last_span.hi,
class_name,
ast::item_class(ty_params, items,
ast::item_class(ty_params, ms,
{node: {id: ctor_id,
self_id: p.get_id(),
dec: ct_d,
@@ -2112,16 +2103,10 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
// lets us identify the constructor declaration at
// parse time
// we don't really want just the fn_decl...
enum class_contents { ctor_decl(ast::fn_decl, ast::blk, codemap::span),
// assumed to be public
plain_decl(ast::class_member, codemap::span),
// contents of a priv section --
// parse_class_item ensures that
// none of these are a ctor decl
priv_decls([(ast::class_member, codemap::span)])}
members([@ast::class_member]) }
fn parse_class_item(p:parser, class_name:@ast::path) -> class_contents {
fn parse_class_item(p:parser, class_name:@ast::path) -> class_contents {
if eat_word(p, "new") {
let lo = p.last_span.lo;
// Can ctors have attrs?
@@ -2140,28 +2125,28 @@ enum class_contents { ctor_decl(ast::fn_decl, ast::blk, codemap::span),
let mut results = [];
while p.token != token::RBRACE {
if eat_word(p, "let") {
let a_var = parse_instance_var(p);
let a_var = parse_instance_var(p, ast::priv);
expect(p, token::SEMI);
results += [a_var];
}
else {
let m = parse_method(p);
results += [(ast::class_method(m), m.span)];
let m = parse_method(p, ast::priv);
results += [@{node: ast::class_method(m), span: m.span}];
}
}
p.bump();
ret priv_decls(results);
ret members(results);
}
else {
// Probably need to parse attrs
ret if eat_word(p, "let") {
let (a_var, a_span) = parse_instance_var(p);
let ivar = parse_instance_var(p, ast::pub);
expect(p, token::SEMI);
plain_decl(a_var, a_span)
members([ivar])
}
else {
let m = parse_method(p);
plain_decl(ast::class_method(m), m.span)
let m = parse_method(p, ast::pub);
members([@{node: ast::class_method(m), span: m.span}])
}
}
}