2012-12-03 16:48:01 -08:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2012-11-18 15:55:03 -08:00
|
|
|
use parser::Parser;
|
2012-09-04 11:37:29 -07:00
|
|
|
use attr::parser_attr;
|
2013-01-30 09:56:33 -08:00
|
|
|
use codemap::{span, mk_sp};
|
2011-02-24 15:54:55 -08:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
type ctx =
|
2012-05-23 15:06:11 -07:00
|
|
|
@{sess: parse::parse_sess,
|
2011-07-27 14:19:39 +02:00
|
|
|
cfg: ast::crate_cfg};
|
2011-02-24 15:54:55 -08:00
|
|
|
|
2012-06-25 20:00:46 -07:00
|
|
|
fn eval_crate_directives(cx: ctx,
|
2012-06-29 16:26:56 -07:00
|
|
|
cdirs: ~[@ast::crate_directive],
|
2012-08-24 15:28:43 -07:00
|
|
|
prefix: &Path,
|
2012-10-05 16:17:10 -07:00
|
|
|
view_items: &mut~[@ast::view_item],
|
|
|
|
items: &mut~[@ast::item]) {
|
2012-06-30 16:19:07 -07:00
|
|
|
for cdirs.each |sub_cdir| {
|
2012-09-19 16:55:01 -07:00
|
|
|
eval_crate_directive(cx, *sub_cdir, prefix, view_items, items);
|
2011-02-24 15:54:55 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 14:41:40 -08:00
|
|
|
pub fn eval_crate_directives_to_mod(cx: ctx, cdirs: ~[@ast::crate_directive],
|
|
|
|
prefix: &Path, suffix: &Option<Path>)
|
2012-06-29 16:26:56 -07:00
|
|
|
-> (ast::_mod, ~[ast::attribute]) {
|
2011-10-29 01:21:43 -07:00
|
|
|
let (cview_items, citems, cattrs)
|
|
|
|
= parse_companion_mod(cx, prefix, suffix);
|
2012-06-29 16:26:56 -07:00
|
|
|
let mut view_items: ~[@ast::view_item] = ~[];
|
|
|
|
let mut items: ~[@ast::item] = ~[];
|
2012-10-05 16:17:10 -07:00
|
|
|
eval_crate_directives(cx, cdirs, prefix, &mut view_items, &mut items);
|
2012-08-01 17:30:05 -07:00
|
|
|
return ({view_items: vec::append(view_items, cview_items),
|
2012-06-27 23:09:51 -07:00
|
|
|
items: vec::append(items, citems)},
|
2011-10-29 01:21:43 -07:00
|
|
|
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.
|
|
|
|
*/
|
2012-08-20 12:23:37 -07:00
|
|
|
fn parse_companion_mod(cx: ctx, prefix: &Path, suffix: &Option<Path>)
|
2012-06-29 16:26:56 -07:00
|
|
|
-> (~[@ast::view_item], ~[@ast::item], ~[ast::attribute]) {
|
2011-10-29 01:21:43 -07:00
|
|
|
|
2012-08-20 12:23:37 -07:00
|
|
|
fn companion_file(prefix: &Path, suffix: &Option<Path>) -> Path {
|
2012-08-24 15:28:43 -07:00
|
|
|
return match *suffix {
|
2012-08-20 12:23:37 -07:00
|
|
|
option::Some(s) => prefix.push_many(s.components),
|
|
|
|
option::None => copy *prefix
|
2012-08-24 15:28:43 -07:00
|
|
|
}.with_filetype("rs");
|
2011-10-29 01:21:43 -07:00
|
|
|
}
|
|
|
|
|
2012-08-24 15:28:43 -07:00
|
|
|
fn file_exists(path: &Path) -> bool {
|
2011-10-29 01:21:43 -07:00
|
|
|
// Crude, but there's no lib function for this and I'm not
|
|
|
|
// up to writing it just now
|
2012-08-06 12:34:08 -07:00
|
|
|
match io::file_reader(path) {
|
2012-08-26 16:54:31 -07:00
|
|
|
result::Ok(_) => true,
|
|
|
|
result::Err(_) => false
|
2011-10-29 01:21:43 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-24 15:28:43 -07:00
|
|
|
let modpath = &companion_file(prefix, suffix);
|
2011-10-29 01:21:43 -07:00
|
|
|
if file_exists(modpath) {
|
2012-08-22 17:24:52 -07:00
|
|
|
debug!("found companion mod");
|
2012-11-18 14:14:40 -08:00
|
|
|
// XXX: Using a dummy span, but this code will go away soon
|
|
|
|
let p0 = new_sub_parser_from_file(cx.sess, cx.cfg,
|
2012-11-18 15:55:03 -08:00
|
|
|
modpath,
|
2013-01-30 09:56:33 -08:00
|
|
|
codemap::dummy_sp());
|
2013-02-21 00:16:31 -08:00
|
|
|
let (inner, next) = p0.parse_inner_attrs_and_next();
|
|
|
|
let m0 = p0.parse_mod_items(token::EOF, next);
|
|
|
|
return (m0.view_items, m0.items, inner);
|
2011-10-29 01:21:43 -07:00
|
|
|
} else {
|
2012-08-01 17:30:05 -07:00
|
|
|
return (~[], ~[], ~[]);
|
2011-10-29 01:21:43 -07:00
|
|
|
}
|
2011-02-24 15:54:55 -08:00
|
|
|
}
|
|
|
|
|
2012-07-18 16:18:02 -07:00
|
|
|
fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
|
2012-08-06 12:34:08 -07:00
|
|
|
match ::attr::first_attr_value_str_by_name(attrs, ~"path") {
|
2012-08-20 12:23:37 -07:00
|
|
|
Some(d) => d,
|
|
|
|
None => default
|
2011-11-22 12:31:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 14:41:40 -08:00
|
|
|
pub fn eval_src_mod(cx: ctx, prefix: &Path,
|
|
|
|
outer_attrs: ~[ast::attribute],
|
|
|
|
id: ast::ident, sp: span)
|
|
|
|
-> (ast::item_, ~[ast::attribute]) {
|
2012-11-09 16:31:44 -08:00
|
|
|
let file_path = Path(cdir_path_opt(
|
|
|
|
cx.sess.interner.get(id) + ~".rs", outer_attrs));
|
2012-11-21 15:51:11 -08:00
|
|
|
eval_src_mod_from_path(cx, prefix, &file_path, outer_attrs, sp)
|
|
|
|
}
|
|
|
|
|
2013-01-29 14:41:40 -08:00
|
|
|
pub fn eval_src_mod_from_path(cx: ctx, prefix: &Path, path: &Path,
|
|
|
|
outer_attrs: ~[ast::attribute],
|
|
|
|
sp: span)
|
|
|
|
-> (ast::item_, ~[ast::attribute]) {
|
2012-11-21 15:51:11 -08:00
|
|
|
let full_path = if path.is_absolute {
|
|
|
|
copy *path
|
2012-11-09 16:31:44 -08:00
|
|
|
} else {
|
2012-11-21 15:51:11 -08:00
|
|
|
prefix.push_many(path.components)
|
2012-11-09 16:31:44 -08:00
|
|
|
};
|
|
|
|
let p0 =
|
2012-11-18 14:14:40 -08:00
|
|
|
new_sub_parser_from_file(cx.sess, cx.cfg,
|
2012-11-18 15:55:03 -08:00
|
|
|
&full_path, sp);
|
2013-02-21 00:16:31 -08:00
|
|
|
let (inner, next) = p0.parse_inner_attrs_and_next();
|
|
|
|
let mod_attrs = vec::append(outer_attrs, inner);
|
|
|
|
let first_item_outer_attrs = next;
|
2012-11-09 16:31:44 -08:00
|
|
|
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)};
|
|
|
|
}
|
|
|
|
|
2012-08-24 15:28:43 -07:00
|
|
|
fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
|
2012-10-05 16:17:10 -07:00
|
|
|
view_items: &mut ~[@ast::view_item],
|
|
|
|
items: &mut ~[@ast::item]) {
|
2012-08-06 12:34:08 -07:00
|
|
|
match cdir.node {
|
2012-09-24 12:53:32 -07:00
|
|
|
ast::cdir_src_mod(vis, id, attrs) => {
|
2012-11-21 15:51:11 -08:00
|
|
|
let (m, mod_attrs) = eval_src_mod(cx, prefix, attrs, id, cdir.span);
|
2012-11-09 16:31:44 -08:00
|
|
|
let i = mk_item(cx, cdir.span.lo, cdir.span.hi,
|
2012-06-21 16:44:10 -07:00
|
|
|
/* FIXME (#2543) */ copy id,
|
2012-11-09 16:31:44 -08:00
|
|
|
m, vis, mod_attrs);
|
2012-09-26 17:33:34 -07:00
|
|
|
items.push(i);
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2012-09-24 12:53:32 -07:00
|
|
|
ast::cdir_dir_mod(vis, id, cdirs, attrs) => {
|
2012-08-24 15:28:43 -07:00
|
|
|
let path = Path(cdir_path_opt(*cx.sess.interner.get(id), attrs));
|
|
|
|
let full_path = if path.is_absolute {
|
|
|
|
copy path
|
|
|
|
} else {
|
|
|
|
prefix.push_many(path.components)
|
|
|
|
};
|
2011-10-29 01:21:43 -07:00
|
|
|
let (m0, a0) = eval_crate_directives_to_mod(
|
2012-08-20 12:23:37 -07:00
|
|
|
cx, cdirs, &full_path, &None);
|
2011-07-27 14:19:39 +02:00
|
|
|
let i =
|
2012-06-21 16:44:10 -07:00
|
|
|
@{ident: /* FIXME (#2543) */ copy id,
|
2012-06-27 23:09:51 -07:00
|
|
|
attrs: vec::append(attrs, a0),
|
2011-07-27 14:19:39 +02:00
|
|
|
id: cx.sess.next_id,
|
|
|
|
node: ast::item_mod(m0),
|
2012-09-24 12:53:32 -07:00
|
|
|
vis: vis,
|
2011-07-27 14:19:39 +02:00
|
|
|
span: cdir.span};
|
|
|
|
cx.sess.next_id += 1;
|
2012-09-26 17:33:34 -07:00
|
|
|
items.push(i);
|
2011-07-27 14:19:39 +02:00
|
|
|
}
|
2012-09-26 17:33:34 -07:00
|
|
|
ast::cdir_view_item(vi) => view_items.push(vi),
|
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:
|
|
|
|
//
|