use syntax::codemap::Pos;
use syntax::parse::token::InternedString;
use syntax::parse::token;
+use syntax::ptr::P;
use rustc::back::link;
use rustc::driver::driver;
use std::rc::Rc;
use std::u32;
-use std::gc::{Gc, GC};
use core::DocContext;
use doctree;
}
}
-impl<T: 'static + Clean<U>, U> Clean<U> for Gc<T> {
+impl<T: Clean<U>, U> Clean<U> for P<T> {
fn clean(&self, cx: &DocContext) -> U {
(**self).clean(cx)
}
impl Clean<Attribute> for ast::Attribute {
fn clean(&self, cx: &DocContext) -> Attribute {
- self.desugar_doc().node.value.clean(cx)
+ self.with_desugared_doc(|a| a.node.value.clean(cx))
}
}
_ => None,
}
}
- fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<ast::MetaItem>]> { None }
+ fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { None }
}
impl<'a> attr::AttrMetaMethods for &'a Attribute {
fn name(&self) -> InternedString { (**self).name() }
fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
- fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<ast::MetaItem>]> { None }
+ fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { None }
}
#[deriving(Clone, Encodable, Decodable, PartialEq)]
match *self {
ast::SelfStatic => SelfStatic,
ast::SelfValue(_) => SelfValue,
- ast::SelfRegion(lt, mt, _) => {
+ ast::SelfRegion(ref lt, ref mt, _) => {
SelfBorrowed(lt.clean(cx), mt.clean(cx))
}
- ast::SelfExplicit(typ, _) => SelfExplicit(typ.clean(cx)),
+ ast::SelfExplicit(ref typ, _) => SelfExplicit(typ.clean(cx)),
}
}
}
TyRptr(ref l, ref m) =>
BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx),
type_: box m.ty.clean(cx)},
- TyBox(ty) => Managed(box ty.clean(cx)),
- TyUniq(ty) => Unique(box ty.clean(cx)),
- TyVec(ty) => Vector(box ty.clean(cx)),
- TyFixedLengthVec(ty, ref e) => FixedVector(box ty.clean(cx),
- e.span.to_src(cx)),
+ TyBox(ref ty) => Managed(box ty.clean(cx)),
+ TyUniq(ref ty) => Unique(box ty.clean(cx)),
+ TyVec(ref ty) => Vector(box ty.clean(cx)),
+ TyFixedLengthVec(ref ty, ref e) => FixedVector(box ty.clean(cx),
+ e.span.to_src(cx)),
TyTup(ref tys) => Tuple(tys.clean(cx)),
TyPath(ref p, ref tpbs, id) => {
resolve_type(cx, p.clean(cx), tpbs.clean(cx), id)
remaining,
b.clone());
let path = syntax::codemap::dummy_spanned(path);
- ret.push(convert(&ast::ViewItemUse(box(GC) path)));
+ ret.push(convert(&ast::ViewItemUse(P(path))));
}
}
ast::ViewPathSimple(ident, _, id) => {
},
PatTup(ref elts) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
.collect::<Vec<String>>().connect(", ")),
- PatBox(p) => name_from_pat(&*p),
- PatRegion(p) => name_from_pat(&*p),
+ PatBox(ref p) => name_from_pat(&**p),
+ PatRegion(ref p) => name_from_pat(&**p),
PatLit(..) => {
warn!("tried to get argument name from PatLit, \
which is silly in function arguments");
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use rustc;
-use rustc::{driver, middle};
+use rustc::driver::{config, driver, session};
use rustc::middle::{privacy, ty};
use rustc::lint;
use rustc::back::link;
-use syntax::ast;
+use syntax::{ast, ast_map, codemap, diagnostic};
use syntax::parse::token;
-use syntax;
+use syntax::ptr::P;
use std::cell::RefCell;
-use std::gc::GC;
use std::os;
use std::collections::{HashMap, HashSet};
use arena::TypedArena;
/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
pub enum MaybeTyped<'tcx> {
- Typed(middle::ty::ctxt<'tcx>),
- NotTyped(driver::session::Session)
+ Typed(ty::ctxt<'tcx>),
+ NotTyped(session::Session)
}
pub type ExternalPaths = RefCell<Option<HashMap<ast::DefId,
(Vec<String>, clean::TypeKind)>>>;
pub struct DocContext<'tcx> {
- pub krate: ast::Crate,
+ pub krate: &'tcx ast::Crate,
pub maybe_typed: MaybeTyped<'tcx>,
pub src: Path,
pub external_paths: ExternalPaths,
}
impl<'tcx> DocContext<'tcx> {
- pub fn sess<'a>(&'a self) -> &'a driver::session::Session {
+ pub fn sess<'a>(&'a self) -> &'a session::Session {
match self.maybe_typed {
Typed(ref tcx) => &tcx.sess,
NotTyped(ref sess) => sess
pub type Externs = HashMap<String, Vec<String>>;
-/// Parses, resolves, and typechecks the given crate
-fn get_ast_and_resolve<'tcx>(cpath: &Path, libs: Vec<Path>, cfgs: Vec<String>,
- externs: Externs, triple: Option<String>,
- type_arena: &'tcx TypedArena<ty::t_box_>)
- -> (DocContext<'tcx>, CrateAnalysis) {
- use syntax::codemap::dummy_spanned;
- use rustc::driver::driver::{FileInput,
- phase_1_parse_input,
- phase_2_configure_and_expand,
- phase_3_run_analysis_passes};
- use rustc::driver::config::build_configuration;
+pub fn run_core(libs: Vec<Path>, cfgs: Vec<String>, externs: Externs,
+ cpath: &Path, triple: Option<String>)
+ -> (clean::Crate, CrateAnalysis) {
- let input = FileInput(cpath.clone());
+ // Parse, resolve, and typecheck the given crate.
+
+ let input = driver::FileInput(cpath.clone());
let warning_lint = lint::builtin::WARNINGS.name_lower();
- let sessopts = driver::config::Options {
+ let sessopts = config::Options {
maybe_sysroot: Some(os::self_exe_path().unwrap().dir_path()),
addl_lib_search_paths: RefCell::new(libs),
- crate_types: vec!(driver::config::CrateTypeRlib),
+ crate_types: vec!(config::CrateTypeRlib),
lint_opts: vec!((warning_lint, lint::Allow)),
externs: externs,
- target_triple: triple.unwrap_or(driver::driver::host_triple().to_string()),
- ..rustc::driver::config::basic_options().clone()
+ target_triple: triple.unwrap_or(driver::host_triple().to_string()),
+ ..config::basic_options().clone()
};
- let codemap = syntax::codemap::CodeMap::new();
- let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto, None);
+ let codemap = codemap::CodeMap::new();
+ let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto, None);
let span_diagnostic_handler =
- syntax::diagnostic::mk_span_handler(diagnostic_handler, codemap);
+ diagnostic::mk_span_handler(diagnostic_handler, codemap);
- let sess = driver::session::build_session_(sessopts,
- Some(cpath.clone()),
- span_diagnostic_handler);
+ let sess = session::build_session_(sessopts,
+ Some(cpath.clone()),
+ span_diagnostic_handler);
- let mut cfg = build_configuration(&sess);
+ let mut cfg = config::build_configuration(&sess);
for cfg_ in cfgs.move_iter() {
let cfg_ = token::intern_and_get_ident(cfg_.as_slice());
- cfg.push(box(GC) dummy_spanned(ast::MetaWord(cfg_)));
+ cfg.push(P(codemap::dummy_spanned(ast::MetaWord(cfg_))));
}
- let krate = phase_1_parse_input(&sess, cfg, &input);
+ let krate = driver::phase_1_parse_input(&sess, cfg, &input);
let name = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
&input);
- let (krate, ast_map)
- = phase_2_configure_and_expand(&sess, krate, name.as_slice(), None)
- .expect("phase_2_configure_and_expand aborted in rustdoc!");
+ let krate = driver::phase_2_configure_and_expand(&sess, krate, name.as_slice(), None)
+ .expect("phase_2_configure_and_expand aborted in rustdoc!");
+
+ let mut forest = ast_map::Forest::new(krate);
+ let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
- let driver::driver::CrateAnalysis {
+ let type_arena = TypedArena::new();
+ let driver::CrateAnalysis {
exported_items, public_items, ty_cx, ..
- } = phase_3_run_analysis_passes(sess, &krate, ast_map, type_arena, name);
+ } = driver::phase_3_run_analysis_passes(sess, ast_map, &type_arena, name);
- debug!("crate: {:?}", krate);
- (DocContext {
- krate: krate,
+ let ctxt = DocContext {
+ krate: ty_cx.map.krate(),
maybe_typed: Typed(ty_cx),
src: cpath.clone(),
external_traits: RefCell::new(Some(HashMap::new())),
external_paths: RefCell::new(Some(HashMap::new())),
inlined: RefCell::new(Some(HashSet::new())),
populated_crate_impls: RefCell::new(HashSet::new()),
- }, CrateAnalysis {
+ };
+ debug!("crate: {:?}", ctxt.krate);
+
+ let analysis = CrateAnalysis {
exported_items: exported_items,
public_items: public_items,
external_paths: RefCell::new(None),
external_traits: RefCell::new(None),
external_typarams: RefCell::new(None),
inlined: RefCell::new(None),
- })
-}
-
-pub fn run_core(libs: Vec<Path>, cfgs: Vec<String>, externs: Externs,
- path: &Path, triple: Option<String>)
- -> (clean::Crate, CrateAnalysis) {
- let type_arena = TypedArena::new();
- let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs, externs,
- triple, &type_arena);
+ };
let krate = {
let mut v = RustdocVisitor::new(&ctxt, Some(&analysis));
- v.visit(&ctxt.krate);
+ v.visit(ctxt.krate);
v.clean(&ctxt)
};
use syntax::ast;
use syntax::attr;
use syntax::ast::{Ident, NodeId};
-
-use std::gc::Gc;
+use syntax::ptr::P;
pub struct Module {
pub name: Option<Ident>,
}
pub struct Typedef {
- pub ty: ast::P<ast::Ty>,
+ pub ty: P<ast::Ty>,
pub gen: ast::Generics,
pub name: Ident,
pub id: ast::NodeId,
}
pub struct Static {
- pub type_: ast::P<ast::Ty>,
+ pub type_: P<ast::Ty>,
pub mutability: ast::Mutability,
- pub expr: Gc<ast::Expr>,
+ pub expr: P<ast::Expr>,
pub name: Ident,
pub attrs: Vec<ast::Attribute>,
pub vis: ast::Visibility,
pub struct Impl {
pub generics: ast::Generics,
pub trait_: Option<ast::TraitRef>,
- pub for_: ast::P<ast::Ty>,
+ pub for_: P<ast::Ty>,
pub items: Vec<ast::ImplItem>,
pub attrs: Vec<ast::Attribute>,
pub whence: Span,
use std::cell::RefCell;
use std::char;
use std::dynamic_lib::DynamicLibrary;
-use std::gc::GC;
use std::io::{Command, TempDir};
use std::io;
use std::os;
use syntax::codemap::{CodeMap, dummy_spanned};
use syntax::diagnostic;
use syntax::parse::token;
+use syntax::ptr::P;
use core;
use clean;
let mut cfg = config::build_configuration(&sess);
cfg.extend(cfgs.move_iter().map(|cfg_| {
let cfg_ = token::intern_and_get_ident(cfg_.as_slice());
- box(GC) dummy_spanned(ast::MetaWord(cfg_))
+ P(dummy_spanned(ast::MetaWord(cfg_)))
}));
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
- let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
- "rustdoc-test", None)
+ let krate = driver::phase_2_configure_and_expand(&sess, krate,
+ "rustdoc-test", None)
.expect("phase_2_configure_and_expand aborted in rustdoc!");
let ctx = core::DocContext {
- krate: krate,
+ krate: &krate,
maybe_typed: core::NotTyped(sess),
src: input_path,
external_paths: RefCell::new(Some(HashMap::new())),
};
let mut v = RustdocVisitor::new(&ctx, None);
- v.visit(&ctx.krate);
+ v.visit(ctx.krate);
let mut krate = v.clean(&ctx);
match crate_name {
Some(name) => krate.name = name,
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::Span;
+use syntax::ptr::P;
use rustc::middle::stability;
-use std::gc::{Gc, GC};
-
use core;
use doctree::*;
}
pub fn visit(&mut self, krate: &ast::Crate) {
- self.attrs = krate.attrs.iter().map(|x| (*x).clone()).collect();
+ self.attrs = krate.attrs.clone();
self.module = self.visit_mod_contents(krate.span,
- krate.attrs
- .iter()
- .map(|x| *x)
- .collect(),
+ krate.attrs.clone(),
ast::Public,
ast::CRATE_NODE_ID,
&krate.module,
self.module.is_crate = true;
}
- pub fn visit_struct_def(&mut self, item: &ast::Item, sd: Gc<ast::StructDef>,
+ pub fn visit_struct_def(&mut self, item: &ast::Item,
+ name: ast::Ident, sd: &ast::StructDef,
generics: &ast::Generics) -> Struct {
debug!("Visiting struct");
let struct_type = struct_type_from_def(&*sd);
Struct {
id: item.id,
struct_type: struct_type,
- name: item.ident,
+ name: name,
vis: item.vis,
stab: self.stability(item.id),
- attrs: item.attrs.iter().map(|x| *x).collect(),
+ attrs: item.attrs.clone(),
generics: generics.clone(),
- fields: sd.fields.iter().map(|x| (*x).clone()).collect(),
+ fields: sd.fields.clone(),
whence: item.span
}
}
- pub fn visit_enum_def(&mut self, it: &ast::Item, def: &ast::EnumDef,
+ pub fn visit_enum_def(&mut self, it: &ast::Item,
+ name: ast::Ident, def: &ast::EnumDef,
params: &ast::Generics) -> Enum {
debug!("Visiting enum");
- let mut vars: Vec<Variant> = Vec::new();
- for x in def.variants.iter() {
- vars.push(Variant {
- name: x.node.name,
- attrs: x.node.attrs.iter().map(|x| *x).collect(),
- vis: x.node.vis,
- stab: self.stability(x.node.id),
- id: x.node.id,
- kind: x.node.kind.clone(),
- whence: x.span,
- });
- }
Enum {
- name: it.ident,
- variants: vars,
+ name: name,
+ variants: def.variants.iter().map(|v| Variant {
+ name: v.node.name,
+ attrs: v.node.attrs.clone(),
+ vis: v.node.vis,
+ stab: self.stability(v.node.id),
+ id: v.node.id,
+ kind: v.node.kind.clone(),
+ whence: v.span,
+ }).collect(),
vis: it.vis,
stab: self.stability(it.id),
generics: params.clone(),
- attrs: it.attrs.iter().map(|x| *x).collect(),
+ attrs: it.attrs.clone(),
id: it.id,
whence: it.span,
}
}
- pub fn visit_fn(&mut self, item: &ast::Item, fd: &ast::FnDecl,
+ pub fn visit_fn(&mut self, item: &ast::Item,
+ name: ast::Ident, fd: &ast::FnDecl,
fn_style: &ast::FnStyle, _abi: &abi::Abi,
gen: &ast::Generics) -> Function {
debug!("Visiting fn");
id: item.id,
vis: item.vis,
stab: self.stability(item.id),
- attrs: item.attrs.iter().map(|x| *x).collect(),
+ attrs: item.attrs.clone(),
decl: fd.clone(),
- name: item.ident,
+ name: name,
whence: item.span,
generics: gen.clone(),
fn_style: *fn_style,
om.stab = self.stability(id);
om.id = id;
for i in m.items.iter() {
- self.visit_item(&**i, &mut om);
+ self.visit_item(&**i, None, &mut om);
}
om
}
});
let item = match item.node {
ast::ViewItemUse(ref vpath) => {
- match self.visit_view_path(*vpath, om, please_inline) {
+ match self.visit_view_path(&**vpath, om, please_inline) {
None => return,
Some(path) => {
ast::ViewItem {
om.view_items.push(item);
}
- fn visit_view_path(&mut self, path: Gc<ast::ViewPath>,
+ fn visit_view_path(&mut self, path: &ast::ViewPath,
om: &mut Module,
- please_inline: bool) -> Option<Gc<ast::ViewPath>> {
+ please_inline: bool) -> Option<P<ast::ViewPath>> {
match path.node {
ast::ViewPathSimple(dst, _, id) => {
if self.resolve_id(id, Some(dst), false, om, please_inline) {
}
if mine.len() == 0 { return None }
- return Some(box(GC) ::syntax::codemap::Spanned {
+ return Some(P(::syntax::codemap::Spanned {
node: ast::ViewPathList(p.clone(), mine, b.clone()),
span: path.span,
- })
+ }))
}
// these are feature gated anyway
}
}
}
- return Some(path);
+ Some(P(path.clone()))
}
fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
match tcx.map.get(def.node) {
ast_map::NodeItem(it) => {
- let it = match renamed {
- Some(ident) => {
- box(GC) ast::Item {
- ident: ident,
- ..(*it).clone()
- }
- }
- None => it,
- };
if glob {
match it.node {
ast::ItemMod(ref m) => {
self.visit_view_item(vi, om);
}
for i in m.items.iter() {
- self.visit_item(&**i, om);
+ self.visit_item(&**i, None, om);
}
}
_ => { fail!("glob not mapped to a module"); }
}
} else {
- self.visit_item(&*it, om);
+ self.visit_item(it, renamed, om);
}
true
}
}
}
- pub fn visit_item(&mut self, item: &ast::Item, om: &mut Module) {
+ pub fn visit_item(&mut self, item: &ast::Item,
+ renamed: Option<ast::Ident>, om: &mut Module) {
debug!("Visiting item {:?}", item);
+ let name = renamed.unwrap_or(item.ident);
match item.node {
ast::ItemMod(ref m) => {
om.mods.push(self.visit_mod_contents(item.span,
- item.attrs
- .iter()
- .map(|x| *x)
- .collect(),
+ item.attrs.clone(),
item.vis,
item.id,
m,
- Some(item.ident)));
+ Some(name)));
},
ast::ItemEnum(ref ed, ref gen) =>
- om.enums.push(self.visit_enum_def(item, ed, gen)),
- ast::ItemStruct(sd, ref gen) =>
- om.structs.push(self.visit_struct_def(item, sd, gen)),
+ om.enums.push(self.visit_enum_def(item, name, ed, gen)),
+ ast::ItemStruct(ref sd, ref gen) =>
+ om.structs.push(self.visit_struct_def(item, name, &**sd, gen)),
ast::ItemFn(ref fd, ref pur, ref abi, ref gen, _) =>
- om.fns.push(self.visit_fn(item, &**fd, pur, abi, gen)),
- ast::ItemTy(ty, ref gen) => {
+ om.fns.push(self.visit_fn(item, name, &**fd, pur, abi, gen)),
+ ast::ItemTy(ref ty, ref gen) => {
let t = Typedef {
- ty: ty,
+ ty: ty.clone(),
gen: gen.clone(),
- name: item.ident,
+ name: name,
id: item.id,
- attrs: item.attrs.iter().map(|x| *x).collect(),
+ attrs: item.attrs.clone(),
whence: item.span,
vis: item.vis,
stab: self.stability(item.id),
};
om.typedefs.push(t);
},
- ast::ItemStatic(ty, ref mut_, ref exp) => {
+ ast::ItemStatic(ref ty, ref mut_, ref exp) => {
let s = Static {
- type_: ty,
+ type_: ty.clone(),
mutability: mut_.clone(),
expr: exp.clone(),
id: item.id,
- name: item.ident,
- attrs: item.attrs.iter().map(|x| *x).collect(),
+ name: name,
+ attrs: item.attrs.clone(),
whence: item.span,
vis: item.vis,
stab: self.stability(item.id),
},
ast::ItemTrait(ref gen, _, ref b, ref items) => {
let t = Trait {
- name: item.ident,
- items: items.iter().map(|x| (*x).clone()).collect(),
+ name: name,
+ items: items.clone(),
generics: gen.clone(),
bounds: b.iter().map(|x| (*x).clone()).collect(),
id: item.id,
- attrs: item.attrs.iter().map(|x| *x).collect(),
+ attrs: item.attrs.clone(),
whence: item.span,
vis: item.vis,
stab: self.stability(item.id),
};
om.traits.push(t);
},
- ast::ItemImpl(ref gen, ref tr, ty, ref items) => {
+ ast::ItemImpl(ref gen, ref tr, ref ty, ref items) => {
let i = Impl {
generics: gen.clone(),
trait_: tr.clone(),
- for_: ty,
- items: items.iter().map(|x| *x).collect(),
- attrs: item.attrs.iter().map(|x| *x).collect(),
+ for_: ty.clone(),
+ items: items.clone(),
+ attrs: item.attrs.clone(),
id: item.id,
whence: item.span,
vis: item.vis,
fn visit_macro(&self, item: &ast::Item) -> Macro {
Macro {
id: item.id,
- attrs: item.attrs.iter().map(|x| *x).collect(),
+ attrs: item.attrs.clone(),
name: item.ident,
whence: item.span,
stab: self.stability(item.id),