Add sufficient import support to compile some simple single-crate programs.

This is likely not the final solution. It does repetitive work and doesn't produce
errors for invalid but unused imports. In any case, I think it is a useful step.
This commit is contained in:
Rafael Ávila de Espíndola 2011-01-07 17:38:13 -05:00 committed by Graydon Hoare
parent 3c61793b5a
commit 2fb09eb585
6 changed files with 138 additions and 37 deletions

View file

@ -437,6 +437,8 @@ TEST_XFAILS_RUSTC := $(filter-out \
int.rs \
i32-sub.rs \
i8-incr.rs \
import2.rs \
import3.rs \
item-name-overload.rs \
large-records.rs \
lazy-init.rs \

View file

@ -36,7 +36,6 @@ tag def {
def_ty_arg(def_id);
def_binding(def_id);
def_use(def_id);
def_import(def_id);
}
type crate = spanned[crate_];

View file

@ -781,14 +781,14 @@ fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m) -> ast._mod {
let vec[@item] items = vec();
auto index = m.index;
for (@item i in m.items) {
append[@item](items, fold_item[ENV](e, fld, i));
}
for (@view_item vi in m.view_items) {
append[@view_item](view_items, fold_view_item[ENV](e, fld, vi));
}
for (@item i in m.items) {
append[@item](items, fold_item[ENV](e, fld, i));
}
ret fld.fold_mod(e, rec(view_items=view_items, items=items, index=index));
}

View file

@ -24,39 +24,106 @@ tag scope {
type env = rec(list[scope] scopes,
session.session sess);
fn lookup_name(&env e, ast.ident i) -> option.t[def] {
// A simple wrapper over defs that stores a bit more information about modules
// and uses so that we can use the regular lookup_name when resolving imports.
tag def_wrap {
def_wrap_use(@ast.view_item);
def_wrap_mod(@ast.item);
def_wrap_other(def);
}
fn unwrap_def(option.t[def_wrap] d_) -> option.t[def] {
alt (d_) {
case (none[def_wrap]) {
ret none[def];
}
case (some[def_wrap](?d)) {
alt (d) {
case (def_wrap_use(?it)) {
alt (it.node) {
case (ast.view_item_use(_, _, ?id)) {
ret some[def](ast.def_use(id));
}
}
fail;
}
case (def_wrap_mod(?i)) {
alt (i.node) {
case (ast.item_mod(_, _, ?id)) {
ret some[def](ast.def_mod(id));
}
}
fail;
}
case (def_wrap_other(?d)) {
ret some[def](d);
}
}
}
}
fail;
}
// Follow the path of an import and return what it ultimately points to.
fn find_final_def(&env e, vec[ident] idents) -> option.t[def_wrap] {
auto len = _vec.len[ident](idents);
auto first = idents.(0);
if (len == 1u) {
ret lookup_name(e, first);
}
auto d_ = lookup_name(e, first);
alt (d_) {
case (none[def_wrap]) {
ret d_;
}
case (some[def_wrap](?d)) {
alt(d) {
case (def_wrap_mod(?i)) {
auto new_env = update_env_for_item(e, i);
auto new_idents = _vec.slice[ident](idents, 1u, len);
ret find_final_def(new_env, new_idents);
}
}
}
}
fail;
}
fn lookup_name(&env e, ast.ident i) -> option.t[def_wrap] {
// log "resolving name " + i;
fn found_def_item(@ast.item i) -> option.t[def] {
fn found_def_item(@ast.item i) -> option.t[def_wrap] {
alt (i.node) {
case (ast.item_const(_, _, _, ?id, _)) {
ret some[def](ast.def_const(id));
ret some[def_wrap](def_wrap_other(ast.def_const(id)));
}
case (ast.item_fn(_, _, _, ?id, _)) {
ret some[def](ast.def_fn(id));
ret some[def_wrap](def_wrap_other(ast.def_fn(id)));
}
case (ast.item_mod(_, _, ?id)) {
ret some[def](ast.def_mod(id));
ret some[def_wrap](def_wrap_mod(i));
}
case (ast.item_ty(_, _, _, ?id, _)) {
ret some[def](ast.def_ty(id));
ret some[def_wrap](def_wrap_other(ast.def_ty(id)));
}
case (ast.item_tag(_, _, _, ?id)) {
ret some[def](ast.def_ty(id));
ret some[def_wrap](def_wrap_other(ast.def_ty(id)));
}
case (ast.item_obj(_, _, _, ?id, _)) {
ret some[def](ast.def_obj(id));
ret some[def_wrap](def_wrap_other(ast.def_obj(id)));
}
}
}
fn found_decl_stmt(@ast.stmt s) -> option.t[def] {
fn found_decl_stmt(@ast.stmt s) -> option.t[def_wrap] {
alt (s.node) {
case (ast.stmt_decl(?d)) {
alt (d.node) {
case (ast.decl_local(?loc)) {
ret some[def](ast.def_local(loc.id));
auto t = ast.def_local(loc.id);
ret some[def_wrap](def_wrap_other(t));
}
case (ast.decl_item(?it)) {
ret found_def_item(it);
@ -64,26 +131,32 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
}
}
}
ret none[def];
ret none[def_wrap];
}
fn found_def_view(@ast.view_item i) -> option.t[def] {
fn found_def_view(&env e, @ast.view_item i) -> option.t[def_wrap] {
alt (i.node) {
case (ast.view_item_use(_, _, ?id)) {
ret some[def](ast.def_use(id));
ret some[def_wrap](def_wrap_use(i));
}
case (ast.view_item_import(_,?id)) {
ret some[def](ast.def_import(id));
case (ast.view_item_import(?idents,_)) {
auto d = find_final_def(e, idents);
alt (d) {
case (some[def_wrap](_)) {
ret d;
}
}
}
}
fail;
}
fn check_mod(ast.ident i, ast._mod m) -> option.t[def] {
fn check_mod(&env e, ast.ident i, ast._mod m) -> option.t[def_wrap] {
alt (m.index.find(i)) {
case (some[ast.mod_index_entry](?ent)) {
alt (ent) {
case (ast.mie_view_item(?ix)) {
ret found_def_view(m.view_items.(ix));
ret found_def_view(e, m.view_items.(ix));
}
case (ast.mie_item(?ix)) {
ret found_def_item(m.items.(ix));
@ -92,7 +165,8 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
alt (m.items.(item_idx).node) {
case (ast.item_tag(_, ?variants, _, ?tid)) {
auto vid = variants.(variant_idx).id;
ret some[def](ast.def_variant(tid, vid));
auto t = ast.def_variant(tid, vid);
ret some[def_wrap](def_wrap_other(t));
}
case (_) {
log "tag item not actually a tag";
@ -104,15 +178,15 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
}
case (none[ast.mod_index_entry]) { /* fall through */ }
}
ret none[def];
ret none[def_wrap];
}
fn in_scope(ast.ident i, &scope s) -> option.t[def] {
fn in_scope(ast.ident i, env e, &scope s) -> option.t[def_wrap] {
alt (s) {
case (scope_crate(?c)) {
ret check_mod(i, c.node.module);
ret check_mod(e, i, c.node.module);
}
case (scope_item(?it)) {
@ -120,29 +194,33 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
case (ast.item_fn(_, ?f, ?ty_params, _, _)) {
for (ast.arg a in f.inputs) {
if (_str.eq(a.ident, i)) {
ret some[def](ast.def_arg(a.id));
auto t = ast.def_arg(a.id);
ret some[def_wrap](def_wrap_other(t));
}
}
for (ast.ty_param tp in ty_params) {
if (_str.eq(tp.ident, i)) {
ret some[def](ast.def_ty_arg(tp.id));
auto t = ast.def_ty_arg(tp.id);
ret some[def_wrap](def_wrap_other(t));
}
}
}
case (ast.item_obj(_, ?ob, ?ty_params, _, _)) {
for (ast.obj_field f in ob.fields) {
if (_str.eq(f.ident, i)) {
ret some[def](ast.def_obj_field(f.id));
auto t = ast.def_obj_field(f.id);
ret some[def_wrap](def_wrap_other(t));
}
}
for (ast.ty_param tp in ty_params) {
if (_str.eq(tp.ident, i)) {
ret some[def](ast.def_ty_arg(tp.id));
auto t = ast.def_ty_arg(tp.id);
ret some[def_wrap](def_wrap_other(t));
}
}
}
case (ast.item_mod(_, ?m, _)) {
ret check_mod(i, m);
ret check_mod(e, i, m);
}
case (_) { /* fall through */ }
}
@ -160,22 +238,23 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
case (scope_arm(?a)) {
alt (a.index.find(i)) {
case (some[ast.def_id](?did)) {
ret some[def](ast.def_binding(did));
auto t = ast.def_binding(did);
ret some[def_wrap](def_wrap_other(t));
}
case (_) { /* fall through */ }
}
}
}
ret none[def];
ret none[def_wrap];
}
ret std.list.find[scope,def](e.scopes, bind in_scope(i, _));
ret std.list.find[scope,def_wrap](e.scopes, bind in_scope(i, e, _));
}
fn fold_pat_tag(&env e, &span sp, ident i, vec[@ast.pat] args,
option.t[ast.variant_def] old_def, ann a) -> @ast.pat {
auto new_def;
alt (lookup_name(e, i)) {
alt (unwrap_def(lookup_name(e, i))) {
case (some[def](?d)) {
alt (d) {
case (ast.def_variant(?did, ?vid)) {
@ -203,7 +282,7 @@ fn fold_expr_name(&env e, &span sp, &ast.name n,
e.sess.unimpl("resolving name expr with ty params");
}
auto d_ = lookup_name(e, n.node.ident);
auto d_ = unwrap_def(lookup_name(e, n.node.ident));
alt (d_) {
case (some[def](_)) {
@ -232,7 +311,7 @@ fn fold_ty_path(&env e, &span sp, ast.path p,
e.sess.unimpl("resolving path ty with ty params");
}
auto d_ = lookup_name(e, n.node.ident);
auto d_ = unwrap_def(lookup_name(e, n.node.ident));
alt (d_) {
case (some[def](_)) {

View file

@ -0,0 +1,9 @@
import zed.bar;
mod zed {
fn bar() {
log "bar";
}
}
fn main(vec[str] args) {
bar();
}

View file

@ -0,0 +1,12 @@
import zed.bar;
import baz.zed;
mod baz {
mod zed {
fn bar() {
log "bar2";
}
}
}
fn main(vec[str] args) {
bar();
}