2011-06-15 11:19:50 -07:00
|
|
|
|
2011-11-22 12:31:09 +08:00
|
|
|
import front::attr;
|
2011-12-13 16:25:51 -08:00
|
|
|
import core::{option, result};
|
|
|
|
import std::{io, fs};
|
|
|
|
import option::{some, none};
|
2011-07-05 11:48:19 +02:00
|
|
|
import syntax::ast;
|
|
|
|
import syntax::parse::token;
|
2011-09-12 16:33:43 -07:00
|
|
|
import syntax::parse::parser::{parser, new_parser_from_file,
|
2011-09-12 16:13:28 -07:00
|
|
|
parse_inner_attrs_and_next,
|
|
|
|
parse_mod_items, SOURCE_FILE};
|
2011-02-24 15:54:55 -08:00
|
|
|
|
2011-07-01 10:46:59 -07:00
|
|
|
export eval_crate_directives_to_mod;
|
2011-05-03 15:50:56 -07:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
type ctx =
|
2011-07-27 14:19:39 +02:00
|
|
|
@{p: parser,
|
|
|
|
sess: parser::parse_sess,
|
|
|
|
mutable chpos: uint,
|
|
|
|
mutable byte_pos: uint,
|
|
|
|
cfg: ast::crate_cfg};
|
2011-02-24 15:54:55 -08:00
|
|
|
|
2011-09-12 11:27:30 +02:00
|
|
|
fn eval_crate_directives(cx: ctx, cdirs: [@ast::crate_directive], prefix: str,
|
2011-09-12 12:39:38 +02:00
|
|
|
&view_items: [@ast::view_item],
|
|
|
|
&items: [@ast::item]) {
|
2011-08-15 21:54:52 -07:00
|
|
|
for sub_cdir: @ast::crate_directive in cdirs {
|
2011-06-30 17:29:54 -07:00
|
|
|
eval_crate_directive(cx, sub_cdir, prefix, view_items, items);
|
2011-02-24 15:54:55 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-12 11:27:30 +02:00
|
|
|
fn eval_crate_directives_to_mod(cx: ctx, cdirs: [@ast::crate_directive],
|
2011-10-29 01:21:43 -07:00
|
|
|
prefix: str, suffix: option::t<str>)
|
|
|
|
-> (ast::_mod, [ast::attribute]) {
|
2011-12-22 14:42:52 -08:00
|
|
|
#debug("eval crate prefix: %s", prefix);
|
2011-12-22 16:13:40 -08:00
|
|
|
#debug("eval crate suffix: %s",
|
|
|
|
option::from_maybe("none", suffix));
|
2011-10-29 01:21:43 -07:00
|
|
|
let (cview_items, citems, cattrs)
|
|
|
|
= parse_companion_mod(cx, prefix, suffix);
|
2011-08-19 15:16:48 -07:00
|
|
|
let view_items: [@ast::view_item] = [];
|
|
|
|
let items: [@ast::item] = [];
|
2011-06-30 17:29:54 -07:00
|
|
|
eval_crate_directives(cx, cdirs, prefix, view_items, items);
|
2011-10-29 01:21:43 -07:00
|
|
|
ret ({view_items: view_items + cview_items,
|
|
|
|
items: items + citems},
|
|
|
|
cattrs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
The 'companion mod'. So .rc crates and directory mod crate directives define
|
|
|
|
modules but not a .rs file to fill those mods with stuff. The companion mod is
|
|
|
|
a convention for location a .rs file to go with them. For .rc files the
|
|
|
|
companion mod is a .rs file with the same name; for directory mods the
|
|
|
|
companion mod is a .rs file with the same name as the directory.
|
|
|
|
|
|
|
|
We build the path to the companion mod by combining the prefix and the
|
|
|
|
optional suffix then adding the .rs extension.
|
|
|
|
*/
|
|
|
|
fn parse_companion_mod(cx: ctx, prefix: str, suffix: option::t<str>)
|
|
|
|
-> ([@ast::view_item], [@ast::item], [ast::attribute]) {
|
|
|
|
|
|
|
|
fn companion_file(prefix: str, suffix: option::t<str>) -> str {
|
2011-12-29 12:03:39 -08:00
|
|
|
ret alt suffix {
|
2011-10-29 01:21:43 -07:00
|
|
|
option::some(s) { fs::connect(prefix, s) }
|
|
|
|
option::none. { prefix }
|
2011-12-29 12:03:39 -08:00
|
|
|
} + ".rs";
|
2011-10-29 01:21:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn file_exists(path: str) -> bool {
|
|
|
|
// Crude, but there's no lib function for this and I'm not
|
|
|
|
// up to writing it just now
|
|
|
|
alt io::file_reader(path) {
|
|
|
|
result::ok(_) { true }
|
|
|
|
result::err(_) { false }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let modpath = companion_file(prefix, suffix);
|
2011-12-22 14:42:52 -08:00
|
|
|
#debug("looking for companion mod %s", modpath);
|
2011-10-29 01:21:43 -07:00
|
|
|
if file_exists(modpath) {
|
2011-12-22 14:42:52 -08:00
|
|
|
#debug("found companion mod");
|
2011-10-29 01:21:43 -07:00
|
|
|
let p0 = new_parser_from_file(cx.sess, cx.cfg, modpath,
|
|
|
|
cx.chpos, cx.byte_pos, SOURCE_FILE);
|
|
|
|
let inner_attrs = parse_inner_attrs_and_next(p0);
|
|
|
|
let first_item_outer_attrs = inner_attrs.next;
|
|
|
|
let m0 = parse_mod_items(p0, token::EOF, first_item_outer_attrs);
|
|
|
|
cx.chpos = p0.get_chpos();
|
|
|
|
cx.byte_pos = p0.get_byte_pos();
|
|
|
|
ret (m0.view_items, m0.items, inner_attrs.inner);
|
|
|
|
} else {
|
|
|
|
ret ([], [], []);
|
|
|
|
}
|
2011-02-24 15:54:55 -08:00
|
|
|
}
|
|
|
|
|
2011-11-22 12:31:09 +08:00
|
|
|
fn cdir_path_opt(id: str, attrs: [ast::attribute]) -> str {
|
|
|
|
alt attr::get_meta_item_value_str_by_name(attrs, "path") {
|
|
|
|
some(d) {
|
|
|
|
ret d;
|
|
|
|
}
|
|
|
|
none. { ret id; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-12 11:27:30 +02:00
|
|
|
fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str,
|
2011-09-12 12:39:38 +02:00
|
|
|
&view_items: [@ast::view_item],
|
|
|
|
&items: [@ast::item]) {
|
2011-07-27 14:19:39 +02:00
|
|
|
alt cdir.node {
|
2011-11-22 12:31:09 +08:00
|
|
|
ast::cdir_src_mod(id, attrs) {
|
|
|
|
let file_path = cdir_path_opt(id + ".rs", attrs);
|
2011-09-02 15:34:58 -07:00
|
|
|
let full_path =
|
|
|
|
if std::fs::path_is_absolute(file_path) {
|
|
|
|
file_path
|
|
|
|
} else { prefix + std::fs::path_sep() + file_path };
|
2011-07-27 14:19:39 +02:00
|
|
|
let p0 =
|
2011-09-02 15:34:58 -07:00
|
|
|
new_parser_from_file(cx.sess, cx.cfg, full_path, cx.chpos,
|
2011-07-30 15:50:16 -07:00
|
|
|
cx.byte_pos, SOURCE_FILE);
|
2011-07-27 14:19:39 +02:00
|
|
|
let inner_attrs = parse_inner_attrs_and_next(p0);
|
|
|
|
let mod_attrs = attrs + inner_attrs.inner;
|
|
|
|
let first_item_outer_attrs = inner_attrs.next;
|
|
|
|
let m0 = parse_mod_items(p0, token::EOF, first_item_outer_attrs);
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2011-07-27 14:19:39 +02:00
|
|
|
let i =
|
|
|
|
syntax::parse::parser::mk_item(p0, cdir.span.lo, cdir.span.hi, id,
|
|
|
|
ast::item_mod(m0), mod_attrs);
|
|
|
|
// Thread defids, chpos and byte_pos through the parsers
|
|
|
|
cx.chpos = p0.get_chpos();
|
|
|
|
cx.byte_pos = p0.get_byte_pos();
|
2011-08-19 15:16:48 -07:00
|
|
|
items += [i];
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2011-11-22 12:31:09 +08:00
|
|
|
ast::cdir_dir_mod(id, cdirs, attrs) {
|
|
|
|
let path = cdir_path_opt(id, attrs);
|
2011-07-27 14:19:39 +02:00
|
|
|
let full_path =
|
2011-08-25 17:00:12 -07:00
|
|
|
if std::fs::path_is_absolute(path) {
|
2011-08-27 00:23:12 -07:00
|
|
|
path
|
2011-09-02 15:34:58 -07:00
|
|
|
} else { prefix + std::fs::path_sep() + path };
|
2011-10-29 01:21:43 -07:00
|
|
|
let (m0, a0) = eval_crate_directives_to_mod(
|
|
|
|
cx, cdirs, full_path, none);
|
2011-07-27 14:19:39 +02:00
|
|
|
let i =
|
|
|
|
@{ident: id,
|
2011-10-29 01:21:43 -07:00
|
|
|
attrs: attrs + a0,
|
2011-07-27 14:19:39 +02:00
|
|
|
id: cx.sess.next_id,
|
|
|
|
node: ast::item_mod(m0),
|
|
|
|
span: cdir.span};
|
|
|
|
cx.sess.next_id += 1;
|
2011-08-19 15:16:48 -07:00
|
|
|
items += [i];
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2011-08-19 15:16:48 -07:00
|
|
|
ast::cdir_view_item(vi) { view_items += [vi]; }
|
2011-07-27 14:19:39 +02:00
|
|
|
ast::cdir_syntax(pth) { }
|
2011-02-24 15:54:55 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// End:
|
|
|
|
//
|