Created
December 20, 2014 00:30
-
-
Save pmsanford/066697b08e59e6bd3893 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate syntax; | |
extern crate rustc; | |
use syntax::diagnostic::SpanHandler; | |
use syntax::codemap::Span; | |
use syntax::ast::{Item, Item_}; | |
struct StructPkg { | |
pub name: String, | |
pub def: Item, | |
pub impls: Vec<Item> | |
} | |
impl StructPkg { | |
pub fn from_item(itm: &Item) -> StructPkg { | |
let name = String::from_str(itm.ident.name.as_str()); | |
let def = itm.clone(); | |
let impls: Vec<Item> = Vec::new(); | |
StructPkg { | |
name: name, | |
def: def, | |
impls: impls | |
} | |
} | |
} | |
enum AstItem { | |
StructDef(StructPkg), | |
Other(Span) | |
} | |
fn main() { | |
use std::io; | |
use std::io::Reader as rdr; | |
use std::str; | |
use syntax::parse; | |
use syntax::parse::parser::Parser; | |
use syntax::diagnostics::registry::Registry; | |
use rustc::session; | |
use rustc::session::config::{ | |
CrateType, Options | |
}; | |
use syntax::parse::lexer; | |
use std::collections::HashMap; | |
use syntax::codemap::{BytePos, ExpnId}; | |
let opt = Options { | |
crate_types: vec![CrateType::CrateTypeRlib], | |
.. session::config::basic_options() | |
}; | |
let reg = Registry::new(&rustc::DIAGNOSTICS); | |
let session = session::build_session(opt, None, reg); | |
let cfg = session::config::build_configuration(&session); | |
let sess = parse::new_parse_sess(); | |
let source = io::stdin().read_to_end().unwrap(); | |
let str_src = str::from_utf8(source.as_slice()).unwrap(); | |
let fm = parse::string_to_filemap(&sess, str_src.to_string(), | |
"<stdin>".to_string()); | |
let lexer = lexer::StringReader::new(&sess.span_diagnostic, | |
fm); | |
let lex_ptr = box lexer; | |
let mut parsr = Parser::new(&sess, cfg, lex_ptr); | |
let cr = parsr.parse_crate_mod(); | |
let mut hm = HashMap::new(); | |
for item_ptr in cr.module.items.iter() { | |
match item_ptr.node { | |
Item_::ItemStruct(_, _) => { | |
let spkg = StructPkg::from_item(item_ptr.deref()); | |
hm.insert(spkg.name.clone(), AstItem::StructDef(spkg)); | |
}, | |
Item_::ItemImpl(_, _, _, _, _) => {}, | |
_ => { | |
hm.insert(String::from_str(item_ptr.ident.name.as_str()), | |
AstItem::Other(item_ptr.span)); | |
} | |
} | |
} | |
for item_ptr in cr.module.items.iter() { | |
match item_ptr.node { | |
Item_::ItemImpl(_, _, Some(_), _, _) => { | |
let name = String::from_str(item_ptr.ident.name.as_str()); | |
let name_pieces: Vec<&str> = name.split('.').collect(); | |
let name_str = String::from_str(name_pieces[0]); | |
if let AstItem::StructDef(ref mut spkg) = | |
*hm.get_mut(&name_str).unwrap() { | |
spkg.impls.push(item_ptr.deref().clone()); | |
} | |
}, | |
Item_::ItemImpl(_, _, _, _, _) => { | |
if let AstItem::StructDef(ref mut spkg) = | |
*hm.get_mut(&String::from_str(item_ptr.ident.name.as_str())) | |
.unwrap() { | |
spkg.impls.push(item_ptr.deref().clone()); | |
} | |
}, | |
_ => {} | |
} | |
} | |
let first_spn_start = { | |
let mut start = cr.module.items[0].span.lo; | |
if start != BytePos(0u32) { | |
start = start - BytePos(1u32); | |
for item_ptr in cr.module.items.iter() { | |
if item_ptr.span.lo < start { | |
if item_ptr.span.lo == BytePos(0u32) { | |
start = BytePos(0u32); | |
break; | |
} | |
start = item_ptr.span.lo - BytePos(1u32); | |
} | |
} | |
} | |
start | |
}; | |
let opening_spn = Span { | |
lo: BytePos(0u32), | |
hi: first_spn_start, | |
expn_id: ExpnId::from_llvm_cookie(0) | |
}; | |
println!("{}", txt(&opening_spn, &sess.span_diagnostic)); | |
for (_, enm) in hm.iter() { | |
match *enm { | |
AstItem::StructDef(ref itm) => { | |
println!("{}", | |
txt(&itm.def.span, &sess.span_diagnostic)); | |
for impl_itm in itm.impls.iter() { | |
println!(""); | |
println!("{}", txt(&impl_itm.span, &sess.span_diagnostic)); | |
} | |
println!(""); | |
}, | |
AstItem::Other(spn) => { | |
println!("{}", txt(&spn, &sess.span_diagnostic)); | |
println!(""); | |
} | |
} | |
} | |
} | |
fn txt(sp: &Span, sh: &SpanHandler) -> String { | |
sh.cm.span_to_snippet(*sp).unwrap() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment