diff options
| author | Graydon Hoare <graydon@mozilla.com> | 2012-02-17 23:05:20 -0800 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2012-02-17 23:05:20 -0800 |
| commit | ef6f6285893ca2546d740771b4c8046bfa68f668 (patch) | |
| tree | 78c00965b1b06d7920ab4a64097bbf9c8b635b78 /src/comp/syntax | |
| parent | 6f708968549b346611e8172b02612f3c32ca4feb (diff) | |
| download | rust-ef6f6285893ca2546d740771b4c8046bfa68f668.tar.gz rust-ef6f6285893ca2546d740771b4c8046bfa68f668.zip | |
Refactor view_path to parse (but not yet process) export globs, unify code paths.
Diffstat (limited to 'src/comp/syntax')
| -rw-r--r-- | src/comp/syntax/ast.rs | 32 | ||||
| -rw-r--r-- | src/comp/syntax/ast_util.rs | 63 | ||||
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 183 | ||||
| -rw-r--r-- | src/comp/syntax/print/pprust.rs | 89 |
4 files changed, 164 insertions, 203 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index 3a365e58bbd..a76b6f9919f 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -441,26 +441,36 @@ type variant_ = {name: ident, attrs: [attribute], args: [variant_arg], type variant = spanned<variant_>; -type view_item = spanned<view_item_>; // FIXME: May want to just use path here, which would allow things like // 'import ::foo' type simple_path = [ident]; -type import_ident_ = {name: ident, id: node_id}; +type path_list_ident_ = {name: ident, id: node_id}; +type path_list_ident = spanned<path_list_ident_>; + +type view_path = spanned<view_path_>; +enum view_path_ { + + // quux = foo::bar::baz + // + // or just + // + // foo::bar::baz (with 'baz =' implicitly on the left) + view_path_simple(ident, @simple_path, node_id), -type import_ident = spanned<import_ident_>; + // foo::bar::* + view_path_glob(@simple_path, node_id), + // foo::bar::{a,b,c} + view_path_list(@simple_path, [path_list_ident], node_id) +} + +type view_item = spanned<view_item_>; enum view_item_ { view_item_use(ident, [@meta_item], node_id), - view_item_import(ident, @simple_path, node_id), - view_item_import_glob(@simple_path, node_id), - view_item_import_from(@simple_path, [import_ident], node_id), - view_item_export([ident], node_id), - // export foo::{} - view_item_export_enum_none(ident, node_id), - // export foo::{bar, baz, blat} - view_item_export_enum_some(ident, [import_ident], node_id) + view_item_import([@view_path]), + view_item_export([@view_path]) } // Meta-data associated with an item diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index cd508aae90b..09242f40c42 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -116,56 +116,63 @@ fn float_ty_to_str(t: float_ty) -> str { } fn is_exported(i: ident, m: _mod) -> bool { - let nonlocal = true; + let local = false; let parent_enum : option<ident> = none; for it: @item in m.items { - if it.ident == i { nonlocal = false; } + if it.ident == i { local = true; } alt it.node { item_enum(variants, _) { for v: variant in variants { if v.node.name == i { - nonlocal = false; + local = true; parent_enum = some(it.ident); } } } _ { } } - if !nonlocal { break; } + if local { break; } } - let count = 0u; + let has_explicit_exports = false; for vi: @view_item in m.view_items { alt vi.node { - view_item_export(ids, _) { - // If any of ids is a enum, we want to consider - // all the variants to be exported - for id in ids { - if str::eq(i, id) { ret true; } - alt parent_enum { - some(parent_enum_id) { - if str::eq(id, parent_enum_id) { ret true; } + view_item_export(vps) { + has_explicit_exports = true; + for vp in vps { + alt vp.node { + ast::view_path_simple(id, _, _) { + if id == i { ret true; } + alt parent_enum { + some(parent_enum_id) { + if id == parent_enum_id { ret true; } + } + _ {} } - _ { } - } + } + + ast::view_path_list(path, ids, _) { + if vec::len(*path) == 1u { + if i == path[0] { ret true; } + for id in ids { + if id.node.name == i { ret true; } + } + } else { + fail "export of path-qualified list"; + } + } + + // FIXME: glob-exports aren't supported yet. + _ {} + } } - count += 1u; - } - view_item_export_enum_none(id, _) { - if str::eq(i, id) { ret true; } - count += 1u; - } - view_item_export_enum_some(id, ids, _) { - if str::eq(i, id) { ret true; } - for id in ids { if str::eq(i, id.node.name) { ret true; } } - count += 1u; } - _ {/* fall through */ } + _ {} } } // If there are no declared exports then // everything not imported is exported - // even if it's nonlocal (since it's explicit) - ret count == 0u && !nonlocal; + // even if it's local (since it's explicit) + ret !has_explicit_exports && local; } pure fn is_call_expr(e: @expr) -> bool { diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 1e21dff0b34..eb34fb4b89d 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -202,7 +202,7 @@ fn parse_ident(p: parser) -> ast::ident { } } -fn parse_import_ident(p: parser) -> ast::import_ident { +fn parse_path_list_ident(p: parser) -> ast::path_list_ident { let lo = p.span.lo; let ident = parse_ident(p); let hi = p.span.hi; @@ -2421,139 +2421,80 @@ fn parse_use(p: parser) -> ast::view_item_ { ret ast::view_item_use(ident, metadata, p.get_id()); } -fn parse_rest_import_name(p: parser, first: ast::ident, - def_ident: option<ast::ident>) -> - ast::view_item_ { - let identifiers: [ast::ident] = [first]; - let glob: bool = false; - let from_idents = option::none::<[ast::import_ident]>; - while true { - alt p.token { - token::SEMI { break; } - token::MOD_SEP { - if glob { p.fatal("cannot path into a glob"); } - if option::is_some(from_idents) { - p.fatal("cannot path into import list"); - } +fn parse_view_path(p: parser) -> @ast::view_path { + let lo = p.span.lo; + let first_ident = parse_ident(p); + let path = [first_ident]; + #debug("parsed view_path: %s", first_ident); + alt p.token { + token::EQ { + // x = foo::bar + p.bump(); + path = [parse_ident(p)]; + while p.token == token::MOD_SEP { p.bump(); - } - _ { p.fatal("expecting '::' or ';'"); } + let id = parse_ident(p); + path += [id]; } - alt p.token { - token::IDENT(_, _) { identifiers += [parse_ident(p)]; } - - - - + let hi = p.span.hi; + ret @spanned(lo, hi, + ast::view_path_simple(first_ident, + @path, p.get_id())); + } - //the lexer can't tell the different kinds of stars apart ) : - token::BINOP(token::STAR) { - glob = true; + token::MOD_SEP { + // foo::bar or foo::{a,b,c} or foo::* + while p.token == token::MOD_SEP { p.bump(); - } + alt p.token { + token::IDENT(i, _) { + p.bump(); + path += [p.get_str(i)]; + } + // foo::bar::{a,b,c} + token::LBRACE { + let idents = + parse_seq(token::LBRACE, token::RBRACE, + seq_sep(token::COMMA), + parse_path_list_ident, p).node; + let hi = p.span.hi; + ret @spanned(lo, hi, + ast::view_path_list(@path, idents, + p.get_id())); + } + // foo::bar::* + token::BINOP(token::STAR) { + p.bump(); + let hi = p.span.hi; + ret @spanned(lo, hi, + ast::view_path_glob(@path, + p.get_id())); + } - token::LBRACE { - let from_idents_ = - parse_seq(token::LBRACE, token::RBRACE, seq_sep(token::COMMA), - parse_import_ident, p).node; - if vec::is_empty(from_idents_) { - p.fatal("at least one import is required"); + _ { break; } } - from_idents = some(from_idents_); - } - - - - - - _ { - p.fatal("expecting an identifier, or '*'"); - } - } - } - alt def_ident { - some(i) { - if glob { p.fatal("globbed imports can't be renamed"); } - if option::is_some(from_idents) { - p.fatal("can't rename import list"); - } - ret ast::view_item_import(i, @identifiers, p.get_id()); - } - _ { - if glob { - ret ast::view_item_import_glob(@identifiers, p.get_id()); - } else if option::is_some(from_idents) { - ret ast::view_item_import_from(@identifiers, - option::get(from_idents), - p.get_id()); - } else { - let len = vec::len(identifiers); - ret ast::view_item_import(identifiers[len - 1u], @identifiers, - p.get_id()); } } + _ { } } + let hi = p.span.hi; + let last = path[vec::len(path) - 1u]; + ret @spanned(lo, hi, + ast::view_path_simple(last, @path, + p.get_id())); } -fn parse_full_import_name(p: parser, def_ident: ast::ident) -> - ast::view_item_ { - alt p.token { - token::IDENT(i, _) { +fn parse_view_paths(p: parser) -> [@ast::view_path] { + let vp = [parse_view_path(p)]; + while p.token == token::COMMA { p.bump(); - ret parse_rest_import_name(p, p.get_str(i), some(def_ident)); - } - _ { p.fatal("expecting an identifier"); } - } -} - -fn parse_import(p: parser) -> ast::view_item_ { - alt p.token { - token::IDENT(i, _) { - p.bump(); - alt p.token { - token::EQ { - p.bump(); - ret parse_full_import_name(p, p.get_str(i)); - } - _ { ret parse_rest_import_name(p, p.get_str(i), none); } - } - } - _ { p.fatal("expecting an identifier"); } - } -} - -fn parse_enum_export(p:parser, tyname:ast::ident) -> ast::view_item_ { - let enumnames:[ast::import_ident] = - parse_seq(token::LBRACE, token::RBRACE, - seq_sep(token::COMMA), {|p| parse_import_ident(p) }, p).node; - let id = p.get_id(); - if vec::is_empty(enumnames) { - ret ast::view_item_export_enum_none(tyname, id); - } - else { - ret ast::view_item_export_enum_some(tyname, enumnames, id); - } -} - -fn parse_export(p: parser) -> ast::view_item_ { - let first = parse_ident(p); - alt p.token { - token::MOD_SEP { - p.bump(); - ret parse_enum_export(p, first); - } - t { - if t == token::COMMA { p.bump(); } - let ids = - parse_seq_to_before_end(token::SEMI, seq_sep(token::COMMA), - parse_ident, p); - ret ast::view_item_export(vec::concat([[first], ids]), p.get_id()); - } + vp += [parse_view_path(p)]; } + ret vp; } fn parse_view_item(p: parser) -> @ast::view_item { @@ -2562,8 +2503,12 @@ fn parse_view_item(p: parser) -> @ast::view_item { if eat_word(p, "use") { parse_use(p) } else if eat_word(p, "import") { - parse_import(p) - } else if eat_word(p, "export") { parse_export(p) } else { fail }; + ast::view_item_import(parse_view_paths(p)) + } else if eat_word(p, "export") { + ast::view_item_export(parse_view_paths(p)) + } else { + fail + }; let hi = p.span.lo; expect(p, token::SEMI); ret @spanned(lo, hi, the_item); diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index 343b4500a3d..3d0e8a579dc 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -1333,6 +1333,44 @@ fn print_meta_item(s: ps, &&item: @ast::meta_item) { end(s); } +fn print_simple_path(s: ps, path: ast::simple_path) { + let first = true; + for id in path { + if first { first = false; } else { word(s.s, "::"); } + word(s.s, id); + } +} + +fn print_view_path(s: ps, &&vp: @ast::view_path) { + alt vp.node { + ast::view_path_simple(ident, path, _) { + if path[vec::len(*path)-1u] != ident { + word_space(s, ident); + word_space(s, "="); + } + print_simple_path(s, *path); + } + + ast::view_path_glob(path, _) { + print_simple_path(s, *path); + word(s.s, "::*"); + } + + ast::view_path_list(path, idents, _) { + print_simple_path(s, *path); + word(s.s, "::{"); + commasep(s, inconsistent, idents) {|s, w| + word(s.s, w.node.name) + } + word(s.s, "}"); + } + } +} + +fn print_view_paths(s: ps, vps: [@ast::view_path]) { + commasep(s, inconsistent, vps, print_view_path); +} + fn print_view_item(s: ps, item: @ast::view_item) { hardbreak_if_not_bol(s); maybe_print_comment(s, item.span.lo); @@ -1346,59 +1384,20 @@ fn print_view_item(s: ps, item: @ast::view_item) { pclose(s); } } - ast::view_item_import(id, ids, _) { - head(s, "import"); - if !str::eq(id, ids[vec::len(*ids) - 1u]) { - word_space(s, id); - word_space(s, "="); - } - let first = true; - for elt: ast::ident in *ids { - if first { first = false; } else { word(s.s, "::"); } - word(s.s, elt); - } - } - ast::view_item_import_from(mod_path, idents, _) { - head(s, "import"); - for elt: ast::ident in *mod_path { word(s.s, elt); word(s.s, "::"); } - word(s.s, "{"); - commasep(s, inconsistent, idents, - fn@(s: ps, w: ast::import_ident) { word(s.s, w.node.name) }); - word(s.s, "}"); - } - ast::view_item_import_glob(ids, _) { + + ast::view_item_import(vps) { head(s, "import"); - let first = true; - for elt: ast::ident in *ids { - if first { first = false; } else { word(s.s, "::"); } - word(s.s, elt); - } - word(s.s, "::*"); + print_view_paths(s, vps); } - ast::view_item_export(ids, _) { + + ast::view_item_export(vps) { head(s, "export"); - commasep(s, inconsistent, ids, - fn@(s: ps, &&w: ast::ident) { word(s.s, w) }); - } - ast::view_item_export_enum_none(id, _) { - head(s, "export"); - word(s.s, id); - word(s.s, "::{}"); - } - ast::view_item_export_enum_some(id, ids, _) { - head(s, "export"); - word(s.s, id); - word(s.s, "::{"); - commasep(s, inconsistent, ids, fn@(s:ps, &&w: ast::import_ident) { - word(s.s, w.node.name) }); - word(s.s, "}"); + print_view_paths(s, vps); } } word(s.s, ";"); end(s); // end inner head-block - end(s); // end outer head-block - } |
