diff options
| author | Brian Anderson <banderson@mozilla.com> | 2011-08-16 15:21:30 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-08-17 11:04:56 -0700 |
| commit | cd54e7772040cd268f911e9dfd088ad5f659f552 (patch) | |
| tree | d12ac71b3f3ec50fe345d8064c87f8a5b44a9010 /src/comp | |
| parent | c4ce463f3709c7a8a92941d2e4bfab6db5da550f (diff) | |
| download | rust-cd54e7772040cd268f911e9dfd088ad5f659f552.tar.gz rust-cd54e7772040cd268f911e9dfd088ad5f659f552.zip | |
Allow multiple imports in a single statement
Like so: import foo::{bar, baz};
Issue #817
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/middle/resolve.rs | 44 | ||||
| -rw-r--r-- | src/comp/syntax/ast.rs | 5 | ||||
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 39 | ||||
| -rw-r--r-- | src/comp/syntax/print/pprust.rs | 13 |
4 files changed, 98 insertions, 3 deletions
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index b87f3bbda4b..b879b37f9e8 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -61,6 +61,7 @@ type scopes = list<scope>; tag import_state { todo(@ast::view_item, scopes); // only used for explicit imports + todo_from(@ast::view_item, ast::import_ident, scopes); resolving(span); resolved(option::t<def>, @@ -91,6 +92,7 @@ fn new_ext_hash() -> ext_hash { tag mod_index_entry { mie_view_item(@ast::view_item); + mie_import_ident(node_id); mie_item(@ast::item); mie_native_item(@ast::native_item); mie_tag_variant(/* tag item */@ast::item, /* variant index */uint); @@ -173,6 +175,12 @@ fn map_crate(e: &@env, c: &@ast::crate) { ast::view_item_import(_, ids, id) { e.imports.insert(id, todo(i, sc)); } + ast::view_item_import_from(mod_path, idents, id) { + for ident in idents { + e.imports.insert(ident.node.id, + todo_from(i, ident, sc)); + } + } _ { } } } @@ -238,11 +246,27 @@ fn map_crate(e: &@env, c: &@ast::crate) { } } +fn vi_from_to_vi(from_item: &@ast::view_item, + ident: ast::import_ident) -> @ast::view_item { + alt from_item.node { + ast::view_item_import_from(mod_path, idents, _) { + @ast::respan(ident.span, + ast::view_item_import(ident.node.name, + mod_path + ~[ident.node.name], + ident.node.id)) + } + } +} + fn resolve_imports(e: &env) { for each it: @{key: ast::node_id, val: import_state} in e.imports.items() { alt it.val { todo(item, sc) { resolve_import(e, item, sc); } + todo_from(item, ident, sc) { + let vi = vi_from_to_vi(item, ident); + resolve_import(e, vi, sc); + } resolved(_, _, _) { } } } @@ -941,6 +965,11 @@ fn lookup_import(e: &env, defid: def_id, ns: namespace) -> option::t<def> { resolve_import(e, item, sc); ret lookup_import(e, defid, ns); } + todo_from(item, ident, sc) { + let vi = vi_from_to_vi(item, ident); + resolve_import(e, vi, sc); + ret lookup_import(e, defid, ns); + } resolving(sp) { e.sess.span_err(sp, "cyclic import"); ret none; } resolved(val, typ, md) { ret alt ns { ns_value. { val } ns_type. { typ } ns_module. { md } }; @@ -1044,6 +1073,7 @@ fn lookup_in_mie(e: &env, mie: &mod_index_entry, ns: namespace) -> option::t<def> { alt mie { mie_view_item(view_item) { ret found_view_item(e, view_item, ns); } + mie_import_ident(id) { ret lookup_import(e, local_def(id), ns); } mie_item(item) { ret found_def_item(item, ns); } mie_tag_variant(item, variant_idx) { alt item.node { @@ -1070,7 +1100,6 @@ fn lookup_in_mie(e: &env, mie: &mod_index_entry, ns: namespace) -> } } } - _ { } } ret none::<def>; } @@ -1094,6 +1123,13 @@ fn index_mod(md: &ast::_mod) -> mod_index { add_to_index(index, ident, mie_view_item(it)); } + ast::view_item_import_from(_, idents, _) { + for ident in idents { + add_to_index(index, ident.node.name, + mie_import_ident(ident.node.id)); + } + } + //globbed imports have to be resolved lazily. ast::view_item_import_glob(_, _) | ast::view_item_export(_, _) { } @@ -1128,6 +1164,12 @@ fn index_nmod(md: &ast::native_mod) -> mod_index { { add_to_index(index, ident, mie_view_item(it)); } + ast::view_item_import_from(_, idents, _) { + for ident in idents { + add_to_index(index, ident.node.name, + mie_import_ident(ident.node.id)); + } + } ast::view_item_import_glob(_, _) | ast::view_item_export(_, _) { } } } diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index b286fdaf484..066a0b9675b 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -564,10 +564,15 @@ type view_item = spanned<view_item_>; // 'import ::foo' type simple_path = [ident]; +type import_ident_ = {name: ident, id: node_id}; + +type import_ident = spanned<import_ident_>; + tag 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); } diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index e6b65444029..f92ab2ca6bd 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -2288,11 +2288,17 @@ fn parse_rest_import_name(p: &parser, first: 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.peek() { token::SEMI. { break; } token::MOD_SEP. { - if glob { p.fatal("cannot path into a glob"); } + if glob { + p.fatal("cannot path into a glob"); + } + if option::is_some(from_idents) { + p.fatal("cannot path into import list"); + } p.bump(); } _ { p.fatal("expecting '::' or ';'"); } @@ -2305,17 +2311,46 @@ fn parse_rest_import_name(p: &parser, first: ast::ident, glob = true; p.bump(); } + + token::LBRACE. { + fn parse_import_ident(p: &parser) -> ast::import_ident { + let lo = p.get_lo_pos(); + let ident = parse_ident(p); + let hi = p.get_hi_pos(); + ret spanned(lo, hi, {name: ident, + id: p.get_id()}); + } + let from_idents_ = parse_seq(token::LBRACE, + token::RBRACE, + some(token::COMMA), + parse_import_ident, + p).node; + if vec::is_empty(from_idents_) { + p.fatal("at least one import is required"); + } + 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 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, diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index 43ab6c5c823..a8f694e6755 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -1267,6 +1267,19 @@ fn print_view_item(s: &ps, item: &@ast::view_item) { word(s.s, elt); } } + ast::view_item_import_from(mod_path, idents, _) { + head(s, "import"); + for elt: str 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, _) { head(s, "import"); let first = true; |
