syntax: Add a hack to support the int-template pattern
This commit is contained in:
parent
de0268b693
commit
58e26243a7
5 changed files with 74 additions and 9 deletions
|
@ -5,6 +5,7 @@ use codemap::span;
|
||||||
|
|
||||||
export eval_crate_directives_to_mod;
|
export eval_crate_directives_to_mod;
|
||||||
export eval_src_mod;
|
export eval_src_mod;
|
||||||
|
export eval_src_mod_from_path;
|
||||||
|
|
||||||
type ctx =
|
type ctx =
|
||||||
@{sess: parse::parse_sess,
|
@{sess: parse::parse_sess,
|
||||||
|
@ -84,15 +85,23 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_src_mod(cx: ctx, prefix: &Path, id: ast::ident,
|
fn eval_src_mod(cx: ctx, prefix: &Path,
|
||||||
outer_attrs: ~[ast::attribute],
|
outer_attrs: ~[ast::attribute],
|
||||||
sp: span) -> (ast::item_, ~[ast::attribute]) {
|
id: ast::ident, sp: span
|
||||||
|
) -> (ast::item_, ~[ast::attribute]) {
|
||||||
let file_path = Path(cdir_path_opt(
|
let file_path = Path(cdir_path_opt(
|
||||||
cx.sess.interner.get(id) + ~".rs", outer_attrs));
|
cx.sess.interner.get(id) + ~".rs", outer_attrs));
|
||||||
let full_path = if file_path.is_absolute {
|
eval_src_mod_from_path(cx, prefix, &file_path, outer_attrs, sp)
|
||||||
copy file_path
|
}
|
||||||
|
|
||||||
|
fn eval_src_mod_from_path(cx: ctx, prefix: &Path, path: &Path,
|
||||||
|
outer_attrs: ~[ast::attribute],
|
||||||
|
sp: span
|
||||||
|
) -> (ast::item_, ~[ast::attribute]) {
|
||||||
|
let full_path = if path.is_absolute {
|
||||||
|
copy *path
|
||||||
} else {
|
} else {
|
||||||
prefix.push_many(file_path.components)
|
prefix.push_many(path.components)
|
||||||
};
|
};
|
||||||
let p0 =
|
let p0 =
|
||||||
new_sub_parser_from_file(cx.sess, cx.cfg,
|
new_sub_parser_from_file(cx.sess, cx.cfg,
|
||||||
|
@ -121,7 +130,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
|
||||||
items: &mut ~[@ast::item]) {
|
items: &mut ~[@ast::item]) {
|
||||||
match cdir.node {
|
match cdir.node {
|
||||||
ast::cdir_src_mod(vis, id, attrs) => {
|
ast::cdir_src_mod(vis, id, attrs) => {
|
||||||
let (m, mod_attrs) = eval_src_mod(cx, prefix, id, attrs, cdir.span);
|
let (m, mod_attrs) = eval_src_mod(cx, prefix, attrs, id, cdir.span);
|
||||||
let i = mk_item(cx, cdir.span.lo, cdir.span.hi,
|
let i = mk_item(cx, cdir.span.lo, cdir.span.hi,
|
||||||
/* FIXME (#2543) */ copy id,
|
/* FIXME (#2543) */ copy id,
|
||||||
m, vis, mod_attrs);
|
m, vis, mod_attrs);
|
||||||
|
|
|
@ -2963,7 +2963,7 @@ impl Parser {
|
||||||
fn parse_item_mod(outer_attrs: ~[ast::attribute]) -> item_info {
|
fn parse_item_mod(outer_attrs: ~[ast::attribute]) -> item_info {
|
||||||
let id_span = self.span;
|
let id_span = self.span;
|
||||||
let id = self.parse_ident();
|
let id = self.parse_ident();
|
||||||
if self.token == token::SEMI {
|
let info_ = if self.token == token::SEMI {
|
||||||
self.bump();
|
self.bump();
|
||||||
// This mod is in an external file. Let's go get it!
|
// This mod is in an external file. Let's go get it!
|
||||||
let eval_ctx = @{
|
let eval_ctx = @{
|
||||||
|
@ -2972,8 +2972,9 @@ impl Parser {
|
||||||
};
|
};
|
||||||
let prefix = Path(self.sess.cm.span_to_filename(copy self.span));
|
let prefix = Path(self.sess.cm.span_to_filename(copy self.span));
|
||||||
let prefix = prefix.dir_path();
|
let prefix = prefix.dir_path();
|
||||||
let (m, attrs) = eval::eval_src_mod(eval_ctx, &prefix, id,
|
let (m, attrs) = eval::eval_src_mod(eval_ctx, &prefix,
|
||||||
outer_attrs, id_span);
|
outer_attrs,
|
||||||
|
id, id_span);
|
||||||
(id, m, Some(move attrs))
|
(id, m, Some(move attrs))
|
||||||
} else {
|
} else {
|
||||||
self.expect(token::LBRACE);
|
self.expect(token::LBRACE);
|
||||||
|
@ -2981,6 +2982,40 @@ impl Parser {
|
||||||
let m = self.parse_mod_items(token::RBRACE, inner_attrs.next);
|
let m = self.parse_mod_items(token::RBRACE, inner_attrs.next);
|
||||||
self.expect(token::RBRACE);
|
self.expect(token::RBRACE);
|
||||||
(id, item_mod(m), Some(inner_attrs.inner))
|
(id, item_mod(m), Some(inner_attrs.inner))
|
||||||
|
};
|
||||||
|
|
||||||
|
// XXX: Transitionary hack to do the template work inside core
|
||||||
|
// (int-template, iter-trait). If there's a 'merge' attribute
|
||||||
|
// on the mod, then we'll go and suck in another file and merge
|
||||||
|
// its contents
|
||||||
|
match ::attr::first_attr_value_str_by_name(outer_attrs, ~"merge") {
|
||||||
|
Some(path) => {
|
||||||
|
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 path = Path(path);
|
||||||
|
let (new_mod_item, new_attrs) = eval::eval_src_mod_from_path(
|
||||||
|
eval_ctx, &prefix, &path, ~[], id_span);
|
||||||
|
|
||||||
|
let (main_id, main_mod_item, main_attrs) = info_;
|
||||||
|
let main_attrs = main_attrs.get();
|
||||||
|
|
||||||
|
let (main_mod, new_mod) = match (main_mod_item, new_mod_item) {
|
||||||
|
(item_mod(m), item_mod(n)) => (m, n),
|
||||||
|
_ => self.bug(~"parsed mod item should be mod")
|
||||||
|
};
|
||||||
|
let merged_mod = {
|
||||||
|
view_items: main_mod.view_items + new_mod.view_items,
|
||||||
|
items: main_mod.items + new_mod.items
|
||||||
|
};
|
||||||
|
|
||||||
|
let merged_attrs = main_attrs + new_attrs;
|
||||||
|
(main_id, item_mod(merged_mod), Some(merged_attrs))
|
||||||
|
}
|
||||||
|
None => info_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
src/test/run-pass/mod-merge-hack-inst.rs
Normal file
6
src/test/run-pass/mod-merge-hack-inst.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// xfail-test not a test. used by mod-merge-hack.rs
|
||||||
|
|
||||||
|
mod inst {
|
||||||
|
pub type T = i32;
|
||||||
|
pub const bits: uint = 32;
|
||||||
|
}
|
6
src/test/run-pass/mod-merge-hack-template.rs
Normal file
6
src/test/run-pass/mod-merge-hack-template.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// xfail-test not a test. used by mod-merge-hack.rs
|
||||||
|
|
||||||
|
use T = inst::T;
|
||||||
|
|
||||||
|
pub const bits: uint = inst::bits;
|
||||||
|
pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
|
9
src/test/run-pass/mod-merge-hack.rs
Normal file
9
src/test/run-pass/mod-merge-hack.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// xfail-pretty
|
||||||
|
#[path = "mod-merge-hack-template.rs"]
|
||||||
|
#[merge = "mod-merge-hack-inst.rs"]
|
||||||
|
mod myint32;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert myint32::bits == 32;
|
||||||
|
assert myint32::min(10, 20) == 10;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue