libsyntax: Parse common enum fields
This commit is contained in:
parent
780b3853d1
commit
5c9c9a6a9f
5 changed files with 129 additions and 86 deletions
|
@ -641,7 +641,7 @@ enum variant_kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_serialize]
|
#[auto_serialize]
|
||||||
enum enum_def = { variants: ~[variant] };
|
enum enum_def = { variants: ~[variant], common: option<@struct_def> };
|
||||||
|
|
||||||
#[auto_serialize]
|
#[auto_serialize]
|
||||||
type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind,
|
type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind,
|
||||||
|
|
|
@ -231,7 +231,9 @@ impl state: to_type_decls {
|
||||||
vec::push(items_msg, v);
|
vec::push(items_msg, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
~[cx.item_enum_poly(name, ast::enum_def({ variants: items_msg }),
|
~[cx.item_enum_poly(name,
|
||||||
|
ast::enum_def({ variants: items_msg,
|
||||||
|
common: none }),
|
||||||
self.ty_params)]
|
self.ty_params)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -242,9 +242,34 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
|
||||||
item_enum(ast::enum_def({
|
item_enum(ast::enum_def({
|
||||||
variants: vec::map(enum_definition.variants,
|
variants: vec::map(enum_definition.variants,
|
||||||
|x| fld.fold_variant(x)),
|
|x| fld.fold_variant(x)),
|
||||||
|
common: option::map(enum_definition.common,
|
||||||
|
|x| fold_struct_def(x, fld))
|
||||||
}), fold_ty_params(typms, fld))
|
}), fold_ty_params(typms, fld))
|
||||||
}
|
}
|
||||||
item_class(struct_def, typms) => {
|
item_class(struct_def, typms) => {
|
||||||
|
let struct_def = fold_struct_def(struct_def, fld);
|
||||||
|
item_class(struct_def, /* FIXME (#2543) */ copy typms)
|
||||||
|
}
|
||||||
|
item_impl(tps, ifce, ty, methods) => {
|
||||||
|
item_impl(fold_ty_params(tps, fld),
|
||||||
|
ifce.map(|p| fold_trait_ref(p, fld)),
|
||||||
|
fld.fold_ty(ty),
|
||||||
|
vec::map(methods, |x| fld.fold_method(x)))
|
||||||
|
}
|
||||||
|
item_trait(tps, traits, methods) => {
|
||||||
|
item_trait(fold_ty_params(tps, fld),
|
||||||
|
vec::map(traits, |p| fold_trait_ref(p, fld)),
|
||||||
|
/* FIXME (#2543) */ copy methods)
|
||||||
|
}
|
||||||
|
item_mac(m) => {
|
||||||
|
// FIXME #2888: we might actually want to do something here.
|
||||||
|
item_mac(m)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold)
|
||||||
|
-> @ast::struct_def {
|
||||||
let resulting_optional_constructor;
|
let resulting_optional_constructor;
|
||||||
match struct_def.ctor {
|
match struct_def.ctor {
|
||||||
none => {
|
none => {
|
||||||
|
@ -268,30 +293,11 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
|
||||||
{node: {body: dtor_body,
|
{node: {body: dtor_body,
|
||||||
id: dtor_id with dtor.node}
|
id: dtor_id with dtor.node}
|
||||||
with dtor}};
|
with dtor}};
|
||||||
item_class(@{
|
return @{
|
||||||
traits: vec::map(struct_def.traits,
|
traits: vec::map(struct_def.traits, |p| fold_trait_ref(p, fld)),
|
||||||
|p| fold_trait_ref(p, fld)),
|
members: vec::map(struct_def.members, |x| fld.fold_class_item(x)),
|
||||||
members: vec::map(struct_def.members,
|
|
||||||
|x| fld.fold_class_item(x)),
|
|
||||||
ctor: resulting_optional_constructor,
|
ctor: resulting_optional_constructor,
|
||||||
dtor: dtor},
|
dtor: dtor
|
||||||
/* FIXME (#2543) */ copy typms)
|
|
||||||
}
|
|
||||||
item_impl(tps, ifce, ty, methods) => {
|
|
||||||
item_impl(fold_ty_params(tps, fld),
|
|
||||||
ifce.map(|p| fold_trait_ref(p, fld)),
|
|
||||||
fld.fold_ty(ty),
|
|
||||||
vec::map(methods, |x| fld.fold_method(x)))
|
|
||||||
}
|
|
||||||
item_trait(tps, traits, methods) => {
|
|
||||||
item_trait(fold_ty_params(tps, fld),
|
|
||||||
vec::map(traits, |p| fold_trait_ref(p, fld)),
|
|
||||||
/* FIXME (#2543) */ copy methods)
|
|
||||||
}
|
|
||||||
item_mac(m) => {
|
|
||||||
// FIXME #2888: we might actually want to do something here.
|
|
||||||
item_mac(m)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,7 +576,10 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
|
||||||
enum_variant_kind(enum_definition) => {
|
enum_variant_kind(enum_definition) => {
|
||||||
let variants = vec::map(enum_definition.variants,
|
let variants = vec::map(enum_definition.variants,
|
||||||
|x| fld.fold_variant(x));
|
|x| fld.fold_variant(x));
|
||||||
kind = enum_variant_kind(ast::enum_def({ variants: variants }));
|
let common = option::map(enum_definition.common,
|
||||||
|
|x| fold_struct_def(x, fld));
|
||||||
|
kind = enum_variant_kind(ast::enum_def({ variants: variants,
|
||||||
|
common: common }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,9 +46,9 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
|
||||||
proto_block, proto_box, proto_uniq, provided, public, pure_fn,
|
proto_block, proto_box, proto_uniq, provided, public, pure_fn,
|
||||||
purity, re_anon, re_named, region, rem, required, ret_style,
|
purity, re_anon, re_named, region, rem, required, ret_style,
|
||||||
return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
|
return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
|
||||||
stmt_semi, struct_variant_kind, subtract, sty_box, sty_by_ref,
|
stmt_semi, struct_def, struct_variant_kind, subtract, sty_box,
|
||||||
sty_region, sty_static, sty_uniq, sty_value, token_tree,
|
sty_by_ref, sty_region, sty_static, sty_uniq, sty_value,
|
||||||
trait_method, trait_ref, tt_delim, tt_seq, tt_tok,
|
token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok,
|
||||||
tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
|
tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
|
||||||
ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_param_bound,
|
ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_param_bound,
|
||||||
ty_path, ty_ptr, ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq,
|
ty_path, ty_ptr, ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq,
|
||||||
|
@ -2792,23 +2792,8 @@ class parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_enum_def(ty_params: ~[ast::ty_param]) -> enum_def {
|
fn parse_struct_def(path: @path) -> @struct_def {
|
||||||
let mut variants: ~[variant] = ~[];
|
let mut the_dtor: option<(blk, ~[attribute], codemap::span)> = none;
|
||||||
let mut all_nullary = true, have_disr = false;
|
|
||||||
|
|
||||||
while self.token != token::RBRACE {
|
|
||||||
let variant_attrs = self.parse_outer_attributes();
|
|
||||||
let vlo = self.span.lo;
|
|
||||||
let vis = self.parse_visibility();
|
|
||||||
let ident = self.parse_value_ident();
|
|
||||||
let mut args = ~[], disr_expr = none;
|
|
||||||
let kind;
|
|
||||||
if self.eat(token::LBRACE) {
|
|
||||||
// Parse a struct variant.
|
|
||||||
all_nullary = false;
|
|
||||||
let path = self.ident_to_path_tys(ident, ty_params);
|
|
||||||
let mut the_dtor: option<(blk, ~[attribute], codemap::span)> =
|
|
||||||
none;
|
|
||||||
let mut ms: ~[@class_member] = ~[];
|
let mut ms: ~[@class_member] = ~[];
|
||||||
while self.token != token::RBRACE {
|
while self.token != token::RBRACE {
|
||||||
match self.parse_class_item(path) {
|
match self.parse_class_item(path) {
|
||||||
|
@ -2846,12 +2831,44 @@ class parser {
|
||||||
span: d_s}
|
span: d_s}
|
||||||
};
|
};
|
||||||
|
|
||||||
kind = struct_variant_kind(@{
|
return @{
|
||||||
traits: ~[],
|
traits: ~[],
|
||||||
members: ms,
|
members: ms,
|
||||||
ctor: none,
|
ctor: none,
|
||||||
dtor: actual_dtor
|
dtor: actual_dtor
|
||||||
});
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_enum_def(ident: ast::ident, ty_params: ~[ast::ty_param])
|
||||||
|
-> enum_def {
|
||||||
|
let mut variants: ~[variant] = ~[];
|
||||||
|
let mut all_nullary = true, have_disr = false;
|
||||||
|
let mut common_fields = none;
|
||||||
|
|
||||||
|
while self.token != token::RBRACE {
|
||||||
|
let variant_attrs = self.parse_outer_attributes();
|
||||||
|
let vlo = self.span.lo;
|
||||||
|
|
||||||
|
// Is this a common field declaration?
|
||||||
|
if self.eat_keyword(~"struct") {
|
||||||
|
if common_fields.is_some() {
|
||||||
|
self.fatal(~"duplicate declaration of shared fields");
|
||||||
|
}
|
||||||
|
self.expect(token::LBRACE);
|
||||||
|
let path = self.ident_to_path_tys(ident, ty_params);
|
||||||
|
common_fields = some(self.parse_struct_def(path));
|
||||||
|
again;
|
||||||
|
}
|
||||||
|
|
||||||
|
let vis = self.parse_visibility();
|
||||||
|
let ident = self.parse_value_ident();
|
||||||
|
let mut args = ~[], disr_expr = none;
|
||||||
|
let kind;
|
||||||
|
if self.eat(token::LBRACE) {
|
||||||
|
// Parse a struct variant.
|
||||||
|
all_nullary = false;
|
||||||
|
let path = self.ident_to_path_tys(ident, ty_params);
|
||||||
|
kind = struct_variant_kind(self.parse_struct_def(path));
|
||||||
} else if self.token == token::LPAREN {
|
} else if self.token == token::LPAREN {
|
||||||
all_nullary = false;
|
all_nullary = false;
|
||||||
let arg_tys = self.parse_unspanned_seq(
|
let arg_tys = self.parse_unspanned_seq(
|
||||||
|
@ -2883,7 +2900,7 @@ class parser {
|
||||||
enum");
|
enum");
|
||||||
}
|
}
|
||||||
|
|
||||||
return enum_def({ variants: variants });
|
return enum_def({ variants: variants, common: common_fields });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_item_enum() -> item_info {
|
fn parse_item_enum() -> item_info {
|
||||||
|
@ -2905,12 +2922,13 @@ class parser {
|
||||||
id: self.get_id(),
|
id: self.get_id(),
|
||||||
disr_expr: none,
|
disr_expr: none,
|
||||||
vis: public});
|
vis: public});
|
||||||
return (id, item_enum(enum_def({ variants: ~[variant] }),
|
return (id, item_enum(enum_def({ variants: ~[variant],
|
||||||
|
common: none }),
|
||||||
ty_params), none);
|
ty_params), none);
|
||||||
}
|
}
|
||||||
self.expect(token::LBRACE);
|
self.expect(token::LBRACE);
|
||||||
|
|
||||||
let enum_definition = self.parse_enum_def(ty_params);
|
let enum_definition = self.parse_enum_def(id, ty_params);
|
||||||
(id, item_enum(enum_definition, ty_params), none)
|
(id, item_enum(enum_definition, ty_params), none)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/test/run-pass/common-fields-trivial.rs
Normal file
14
src/test/run-pass/common-fields-trivial.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
enum Foo {
|
||||||
|
struct {
|
||||||
|
x: int;
|
||||||
|
y: int;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bar(int),
|
||||||
|
Baz(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Bar(3);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue