use parser::{Parser, SOURCE_FILE};
use attr::parser_attr;
+use ast_util::mk_sp;
export eval_crate_directives_to_mod;
+export eval_src_mod;
type ctx =
@{sess: parse::parse_sess,
}
}
+fn eval_src_mod(cx: ctx, prefix: &Path, id: ast::ident,
+ outer_attrs: ~[ast::attribute]) -> (ast::item_, ~[ast::attribute]) {
+ let file_path = Path(cdir_path_opt(
+ cx.sess.interner.get(id) + ~".rs", outer_attrs));
+ let full_path = if file_path.is_absolute {
+ copy file_path
+ } else {
+ prefix.push_many(file_path.components)
+ };
+ let p0 =
+ new_parser_from_file(cx.sess, cx.cfg,
+ &full_path, SOURCE_FILE);
+ let inner_attrs = p0.parse_inner_attrs_and_next();
+ let mod_attrs = vec::append(outer_attrs, inner_attrs.inner);
+ let first_item_outer_attrs = inner_attrs.next;
+ let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
+ return (ast::item_mod(m0), mod_attrs);
+}
+
+// XXX: Duplicated from parser.rs
+fn mk_item(ctx: ctx, lo: BytePos, hi: BytePos, +ident: ast::ident,
+ +node: ast::item_, vis: ast::visibility,
+ +attrs: ~[ast::attribute]) -> @ast::item {
+ return @{ident: ident,
+ attrs: attrs,
+ id: next_node_id(ctx.sess),
+ node: node,
+ vis: vis,
+ span: mk_sp(lo, hi)};
+}
+
fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
view_items: &mut ~[@ast::view_item],
items: &mut ~[@ast::item]) {
match cdir.node {
ast::cdir_src_mod(vis, id, attrs) => {
- let file_path = Path(cdir_path_opt(
- cx.sess.interner.get(id) + ~".rs", attrs));
- let full_path = if file_path.is_absolute {
- copy file_path
- } else {
- prefix.push_many(file_path.components)
- };
- let p0 =
- new_parser_from_file(cx.sess, cx.cfg,
- &full_path, SOURCE_FILE);
- let inner_attrs = p0.parse_inner_attrs_and_next();
- let mod_attrs = vec::append(attrs, inner_attrs.inner);
- let first_item_outer_attrs = inner_attrs.next;
- let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
-
- let i = p0.mk_item(cdir.span.lo, cdir.span.hi,
+ let (m, mod_attrs) = eval_src_mod(cx, prefix, id, attrs);
+ let i = mk_item(cx, cdir.span.lo, cdir.span.hi,
/* FIXME (#2543) */ copy id,
- ast::item_mod(m0), vis, mod_attrs);
+ m, vis, mod_attrs);
items.push(i);
}
ast::cdir_dir_mod(vis, id, cdirs, attrs) => {
(id, item_const(ty, e), None)
}
- fn parse_item_mod() -> item_info {
+ fn parse_item_mod(outer_attrs: ~[ast::attribute]) -> item_info {
let id = self.parse_ident();
- self.expect(token::LBRACE);
- let inner_attrs = self.parse_inner_attrs_and_next();
- let m = self.parse_mod_items(token::RBRACE, inner_attrs.next);
- self.expect(token::RBRACE);
- (id, item_mod(m), Some(inner_attrs.inner))
+ if self.token == token::SEMI {
+ self.bump();
+ // This mod is in an external file. Let's go get it!
+ let eval_ctx = @{
+ sess: self.sess,
+ cfg: self.cfg
+ };
+ let prefix = Path(self.sess.cm.span_to_filename(copy self.span));
+ let prefix = prefix.dir_path();
+ let (m, attrs) = eval::eval_src_mod(eval_ctx, &prefix, id, outer_attrs);
+ (id, m, Some(move attrs))
+ } else {
+ self.expect(token::LBRACE);
+ let inner_attrs = self.parse_inner_attrs_and_next();
+ let m = self.parse_mod_items(token::RBRACE, inner_attrs.next);
+ self.expect(token::RBRACE);
+ (id, item_mod(m), Some(inner_attrs.inner))
+ }
}
fn parse_item_foreign_fn( +attrs: ~[attribute]) -> @foreign_item {
return self.parse_item_foreign_mod(lo, visibility, attrs,
items_allowed);
} else if items_allowed && self.eat_keyword(~"mod") {
- let (ident, item_, extra_attrs) = self.parse_item_mod();
+ let (ident, item_, extra_attrs) = self.parse_item_mod(attrs);
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
visibility,
maybe_append(attrs, extra_attrs)));