diff options
| author | Brian Anderson <andersrb@gmail.com> | 2011-04-24 19:40:01 -0400 |
|---|---|---|
| committer | Brian Anderson <andersrb@gmail.com> | 2011-05-01 16:57:36 -0400 |
| commit | 459b0ec8339da2b7ba2f76c3fd110f5b3e971a73 (patch) | |
| tree | e9e7365d9eb768d7ec236d3ca47af0158831b1bf /src | |
| parent | 40624e35d74e5d200ae689c02753f0d60924e668 (diff) | |
| download | rust-459b0ec8339da2b7ba2f76c3fd110f5b3e971a73.tar.gz rust-459b0ec8339da2b7ba2f76c3fd110f5b3e971a73.zip | |
Implement simple module export
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/resolve.rs | 72 | ||||
| -rw-r--r-- | src/test/compile-fail/export-boot.rs | 19 | ||||
| -rw-r--r-- | src/test/compile-fail/export.rs | 4 | ||||
| -rw-r--r-- | src/test/compile-fail/export2.rs | 25 | ||||
| -rw-r--r-- | src/test/run-pass/export-non-interference2.rs | 18 | ||||
| -rw-r--r-- | src/test/run-pass/export-non-interference3.rs | 19 |
6 files changed, 143 insertions, 14 deletions
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 8ea91916a52..82975112816 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -27,8 +27,17 @@ tag scope { scope_arm(ast.arm); } +// This indicates whether we're searching up the scope chain +// or whether we've found a path component and started following +// it back down, which has an effect on export visibility +tag search_direction { + up; + down; +} + type env = rec(list[scope] scopes, - session.session sess); + session.session sess, + search_direction direction); tag namespace { ns_value; @@ -148,7 +157,8 @@ fn find_final_def(&env e, import_map index, auto len = _vec.len[ident](idents); auto rest_idents = _vec.slice[ident](idents, 1u, len); auto empty_e = rec(scopes = nil[scope], - sess = e.sess); + sess = e.sess, + direction = down); auto tmp_e = update_env_for_item(empty_e, i); auto next_i = rest_idents.(0); auto next_ = lookup_name_wrapped(tmp_e, next_i, ns); @@ -172,7 +182,9 @@ fn find_final_def(&env e, import_map index, -> def_wrap { auto len = _vec.len[ident](idents); auto rest_idents = _vec.slice[ident](idents, 1u, len); - auto empty_e = rec(scopes = nil[scope], sess = e.sess); + auto empty_e = rec(scopes = nil[scope], + sess = e.sess, + direction = down); auto tmp_e = update_env_for_external_mod(empty_e, mod_id, idents); auto next_i = rest_idents.(0); auto next_ = lookup_name_wrapped(tmp_e, next_i, ns); @@ -347,8 +359,40 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns) fail; } - fn check_mod(ast.ident i, ast._mod m, namespace ns) + fn check_mod(&env e, ast.ident i, ast._mod m, namespace ns) -> option.t[def_wrap] { + + fn visible(&env e, ast.ident i, ast._mod m) -> bool { + + alt (e.direction) { + case (up) { + ret true; + } + case (down) { + // fall through + } + } + + auto count = 0; + for (@ast.view_item vi in m.view_items) { + alt (vi.node) { + case (ast.view_item_export(?id)) { + if (_str.eq(i, id)) { + ret true; + } + count += 1; + } + case (_) { /* fall through */ } + } + } + // If there are no declared exports then everything is exported + if (count == 0) { + ret true; + } else { + ret false; + } + } + alt (m.index.find(i)) { case (some[ast.mod_index_entry](?ent)) { alt (ent) { @@ -356,7 +400,9 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns) ret some(found_def_view(view_item)); } case (ast.mie_item(?item)) { - ret some(found_def_item(item, ns)); + if (visible(e, i, m)) { + ret some(found_def_item(item, ns)); + } } case (ast.mie_tag_variant(?item, ?variant_idx)) { alt (item.node) { @@ -453,12 +499,12 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns) } } - fn in_scope(&session.session sess, ast.ident identifier, &scope s, + fn in_scope(&env e, ast.ident identifier, &scope s, namespace ns) -> option.t[def_wrap] { alt (s) { case (scope_crate(?c)) { - ret check_mod(identifier, c.node.module, ns); + ret check_mod(e, identifier, c.node.module, ns); } case (scope_item(?it)) { @@ -494,7 +540,7 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns) } } case (ast.item_mod(_, ?m, _)) { - ret check_mod(identifier, m, ns); + ret check_mod(e, identifier, m, ns); } case (ast.item_native_mod(_, ?m, _)) { ret check_native_mod(identifier, m); @@ -522,7 +568,7 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns) } case (scope_external_mod(?mod_id, ?path)) { - ret lookup_external_def(sess, mod_id._0, path); + ret lookup_external_def(e.sess, mod_id._0, path); } case (scope_loop(?d)) { @@ -558,7 +604,7 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns) ret none[tup(@env, def_wrap)]; } case (cons[scope](?hd, ?tl)) { - auto x = in_scope(e.sess, i, hd, ns); + auto x = in_scope(e, i, hd, ns); alt (x) { case (some[def_wrap](?x)) { ret some(tup(@e, x)); @@ -737,7 +783,8 @@ fn resolve_imports(session.session sess, @ast.crate crate) -> @ast.crate { with *fld ); auto e = rec(scopes = nil[scope], - sess = sess); + sess = sess, + direction = up); ret fold.fold_crate[env](e, fld, crate); } @@ -761,7 +808,8 @@ fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate { with *fld ); auto e = rec(scopes = nil[scope], - sess = sess); + sess = sess, + direction = up); ret fold.fold_crate[env](e, fld, new_crate); } diff --git a/src/test/compile-fail/export-boot.rs b/src/test/compile-fail/export-boot.rs new file mode 100644 index 00000000000..7a9fc776fe9 --- /dev/null +++ b/src/test/compile-fail/export-boot.rs @@ -0,0 +1,19 @@ +// xfail-stage0 +// error-pattern: unknown module item + +// rustboot has a different error message than rustc +// this test can die with rustboot, or rustc's error can change + +mod foo { + export x; + fn x(int y) { + log y; + } + fn z(int y) { + log y; + } +} + +fn main() { + foo.z(10); +} diff --git a/src/test/compile-fail/export.rs b/src/test/compile-fail/export.rs index 84e87c2e561..d54e515c6a5 100644 --- a/src/test/compile-fail/export.rs +++ b/src/test/compile-fail/export.rs @@ -1,5 +1,5 @@ -// xfail-stage0 -// error-pattern: unknown module item +// xfail-boot +// error-pattern: unresolved name mod foo { export x; fn x(int y) { diff --git a/src/test/compile-fail/export2.rs b/src/test/compile-fail/export2.rs new file mode 100644 index 00000000000..18e84ddc035 --- /dev/null +++ b/src/test/compile-fail/export2.rs @@ -0,0 +1,25 @@ +// xfail-boot +// error-pattern: unresolved name + +mod foo { + export x; + + fn x() { + bar.x(); + } +} + +mod bar { + export y; + + fn x() { + log "x"; + } + + fn y() { + } +} + +fn main() { + foo.x(); +} diff --git a/src/test/run-pass/export-non-interference2.rs b/src/test/run-pass/export-non-interference2.rs new file mode 100644 index 00000000000..e5b324e4aa7 --- /dev/null +++ b/src/test/run-pass/export-non-interference2.rs @@ -0,0 +1,18 @@ +mod foo { + + export bar; + + mod bar { + fn y() { + x(); + } + } + + fn x() { + log "x"; + } +} + +fn main() { + foo.bar.y(); +} diff --git a/src/test/run-pass/export-non-interference3.rs b/src/test/run-pass/export-non-interference3.rs new file mode 100644 index 00000000000..c52b13f7ec7 --- /dev/null +++ b/src/test/run-pass/export-non-interference3.rs @@ -0,0 +1,19 @@ +mod foo { + export x; + + fn x() { + bar.x(); + } +} + +mod bar { + export x; + + fn x() { + log "x"; + } +} + +fn main() { + foo.x(); +} |
