| //! The document model |
| |
| type AstId = int; |
| |
| type Doc_ = { |
| pages: ~[Page] |
| }; |
| |
| impl Doc_ : cmp::Eq { |
| pure fn eq(other: &Doc_) -> bool { |
| self.pages == (*other).pages |
| } |
| pure fn ne(other: &Doc_) -> bool { !self.eq(other) } |
| } |
| |
| enum Doc { |
| Doc_(Doc_) |
| } |
| |
| impl Doc : cmp::Eq { |
| pure fn eq(other: &Doc) -> bool { *self == *(*other) } |
| pure fn ne(other: &Doc) -> bool { *self != *(*other) } |
| } |
| |
| enum Page { |
| CratePage(CrateDoc), |
| ItemPage(ItemTag) |
| } |
| |
| impl Page : cmp::Eq { |
| pure fn eq(other: &Page) -> bool { |
| match self { |
| CratePage(e0a) => { |
| match (*other) { |
| CratePage(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| ItemPage(e0a) => { |
| match (*other) { |
| ItemPage(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| } |
| } |
| pure fn ne(other: &Page) -> bool { !self.eq(other) } |
| } |
| |
| enum Implementation { |
| Required, |
| Provided, |
| } |
| |
| impl Implementation : cmp::Eq { |
| pure fn eq(other: &Implementation) -> bool { |
| (self as uint) == ((*other) as uint) |
| } |
| pure fn ne(other: &Implementation) -> bool { !self.eq(other) } |
| } |
| |
| |
| /** |
| * Most rustdocs can be parsed into 'sections' according to their markdown |
| * headers |
| */ |
| type Section = { |
| header: ~str, |
| body: ~str |
| }; |
| |
| impl Section : cmp::Eq { |
| pure fn eq(other: &Section) -> bool { |
| self.header == (*other).header && self.body == (*other).body |
| } |
| pure fn ne(other: &Section) -> bool { !self.eq(other) } |
| } |
| |
| // FIXME (#2596): We currently give topmod the name of the crate. There |
| // would probably be fewer special cases if the crate had its own name |
| // and topmod's name was the empty string. |
| type CrateDoc = { |
| topmod: ModDoc, |
| }; |
| |
| impl CrateDoc : cmp::Eq { |
| pure fn eq(other: &CrateDoc) -> bool { |
| self.topmod == (*other).topmod |
| } |
| pure fn ne(other: &CrateDoc) -> bool { !self.eq(other) } |
| } |
| |
| enum ItemTag { |
| ModTag(ModDoc), |
| NmodTag(NmodDoc), |
| ConstTag(ConstDoc), |
| FnTag(FnDoc), |
| EnumTag(EnumDoc), |
| TraitTag(TraitDoc), |
| ImplTag(ImplDoc), |
| TyTag(TyDoc), |
| StructTag(StructDoc) |
| } |
| |
| impl ItemTag : cmp::Eq { |
| pure fn eq(other: &ItemTag) -> bool { |
| match self { |
| ModTag(e0a) => { |
| match (*other) { |
| ModTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| NmodTag(e0a) => { |
| match (*other) { |
| NmodTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| ConstTag(e0a) => { |
| match (*other) { |
| ConstTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| FnTag(e0a) => { |
| match (*other) { |
| FnTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| EnumTag(e0a) => { |
| match (*other) { |
| EnumTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| TraitTag(e0a) => { |
| match (*other) { |
| TraitTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| ImplTag(e0a) => { |
| match (*other) { |
| ImplTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| TyTag(e0a) => { |
| match (*other) { |
| TyTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| StructTag(e0a) => { |
| match (*other) { |
| StructTag(e0b) => e0a == e0b, |
| _ => false |
| } |
| } |
| } |
| } |
| pure fn ne(other: &ItemTag) -> bool { !self.eq(other) } |
| } |
| |
| type ItemDoc = { |
| id: AstId, |
| name: ~str, |
| path: ~[~str], |
| brief: Option<~str>, |
| desc: Option<~str>, |
| sections: ~[Section], |
| // Indicates that this node is a reexport of a different item |
| reexport: bool |
| }; |
| |
| impl ItemDoc : cmp::Eq { |
| pure fn eq(other: &ItemDoc) -> bool { |
| self.id == (*other).id && |
| self.name == (*other).name && |
| self.path == (*other).path && |
| self.brief == (*other).brief && |
| self.desc == (*other).desc && |
| self.sections == (*other).sections && |
| self.reexport == (*other).reexport |
| } |
| pure fn ne(other: &ItemDoc) -> bool { !self.eq(other) } |
| } |
| |
| type SimpleItemDoc = { |
| item: ItemDoc, |
| sig: Option<~str> |
| }; |
| |
| impl SimpleItemDoc : cmp::Eq { |
| pure fn eq(other: &SimpleItemDoc) -> bool { |
| self.item == (*other).item && self.sig == (*other).sig |
| } |
| pure fn ne(other: &SimpleItemDoc) -> bool { !self.eq(other) } |
| } |
| |
| type ModDoc_ = { |
| item: ItemDoc, |
| items: ~[ItemTag], |
| index: Option<Index> |
| }; |
| |
| impl ModDoc_ : cmp::Eq { |
| pure fn eq(other: &ModDoc_) -> bool { |
| self.item == (*other).item && |
| self.items == (*other).items && |
| self.index == (*other).index |
| } |
| pure fn ne(other: &ModDoc_) -> bool { !self.eq(other) } |
| } |
| |
| enum ModDoc { |
| ModDoc_(ModDoc_) |
| } |
| |
| impl ModDoc : cmp::Eq { |
| pure fn eq(other: &ModDoc) -> bool { *self == *(*other) } |
| pure fn ne(other: &ModDoc) -> bool { *self != *(*other) } |
| } |
| |
| type NmodDoc = { |
| item: ItemDoc, |
| fns: ~[FnDoc], |
| index: Option<Index> |
| }; |
| |
| impl NmodDoc : cmp::Eq { |
| pure fn eq(other: &NmodDoc) -> bool { |
| self.item == (*other).item && |
| self.fns == (*other).fns && |
| self.index == (*other).index |
| } |
| pure fn ne(other: &NmodDoc) -> bool { !self.eq(other) } |
| } |
| |
| type ConstDoc = SimpleItemDoc; |
| |
| type FnDoc = SimpleItemDoc; |
| |
| type EnumDoc = { |
| item: ItemDoc, |
| variants: ~[VariantDoc] |
| }; |
| |
| impl EnumDoc : cmp::Eq { |
| pure fn eq(other: &EnumDoc) -> bool { |
| self.item == (*other).item && self.variants == (*other).variants |
| } |
| pure fn ne(other: &EnumDoc) -> bool { !self.eq(other) } |
| } |
| |
| type VariantDoc = { |
| name: ~str, |
| desc: Option<~str>, |
| sig: Option<~str> |
| }; |
| |
| impl VariantDoc : cmp::Eq { |
| pure fn eq(other: &VariantDoc) -> bool { |
| self.name == (*other).name && |
| self.desc == (*other).desc && |
| self.sig == (*other).sig |
| } |
| pure fn ne(other: &VariantDoc) -> bool { !self.eq(other) } |
| } |
| |
| type TraitDoc = { |
| item: ItemDoc, |
| methods: ~[MethodDoc] |
| }; |
| |
| impl TraitDoc : cmp::Eq { |
| pure fn eq(other: &TraitDoc) -> bool { |
| self.item == (*other).item && self.methods == (*other).methods |
| } |
| pure fn ne(other: &TraitDoc) -> bool { !self.eq(other) } |
| } |
| |
| type MethodDoc = { |
| name: ~str, |
| brief: Option<~str>, |
| desc: Option<~str>, |
| sections: ~[Section], |
| sig: Option<~str>, |
| implementation: Implementation, |
| }; |
| |
| impl MethodDoc : cmp::Eq { |
| pure fn eq(other: &MethodDoc) -> bool { |
| self.name == (*other).name && |
| self.brief == (*other).brief && |
| self.desc == (*other).desc && |
| self.sections == (*other).sections && |
| self.sig == (*other).sig && |
| self.implementation == (*other).implementation |
| } |
| pure fn ne(other: &MethodDoc) -> bool { !self.eq(other) } |
| } |
| |
| type ImplDoc = { |
| item: ItemDoc, |
| trait_types: ~[~str], |
| self_ty: Option<~str>, |
| methods: ~[MethodDoc] |
| }; |
| |
| impl ImplDoc : cmp::Eq { |
| pure fn eq(other: &ImplDoc) -> bool { |
| self.item == (*other).item && |
| self.trait_types == (*other).trait_types && |
| self.self_ty == (*other).self_ty && |
| self.methods == (*other).methods |
| } |
| pure fn ne(other: &ImplDoc) -> bool { !self.eq(other) } |
| } |
| |
| type TyDoc = SimpleItemDoc; |
| |
| type StructDoc = { |
| item: ItemDoc, |
| fields: ~[~str], |
| sig: Option<~str> |
| }; |
| |
| impl StructDoc : cmp::Eq { |
| pure fn eq(other: &StructDoc) -> bool { |
| return self.item == other.item |
| && self.fields == other.fields |
| && self.sig == other.sig; |
| } |
| pure fn ne(other: &StructDoc) -> bool { !self.eq(other) } |
| } |
| |
| type Index = { |
| entries: ~[IndexEntry] |
| }; |
| |
| impl Index : cmp::Eq { |
| pure fn eq(other: &Index) -> bool { |
| self.entries == (*other).entries |
| } |
| pure fn ne(other: &Index) -> bool { !self.eq(other) } |
| } |
| |
| /** |
| * A single entry in an index |
| * |
| * Fields: |
| * |
| * * kind - The type of thing being indexed, e.g. 'Module' |
| * * name - The name of the thing |
| * * brief - The brief description |
| * * link - A format-specific string representing the link target |
| */ |
| type IndexEntry = { |
| kind: ~str, |
| name: ~str, |
| brief: Option<~str>, |
| link: ~str |
| }; |
| |
| impl IndexEntry : cmp::Eq { |
| pure fn eq(other: &IndexEntry) -> bool { |
| self.kind == (*other).kind && |
| self.name == (*other).name && |
| self.brief == (*other).brief && |
| self.link == (*other).link |
| } |
| pure fn ne(other: &IndexEntry) -> bool { !self.eq(other) } |
| } |
| |
| impl Doc { |
| fn CrateDoc() -> CrateDoc { |
| option::get(&vec::foldl(None, self.pages, |_m, page| { |
| match *page { |
| doc::CratePage(doc) => Some(doc), |
| _ => None |
| } |
| })) |
| } |
| |
| fn cratemod() -> ModDoc { |
| self.CrateDoc().topmod |
| } |
| } |
| |
| /// Some helper methods on ModDoc, mostly for testing |
| impl ModDoc { |
| |
| fn mods() -> ~[ModDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| ModTag(ModDoc) => Some(ModDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn nmods() -> ~[NmodDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| NmodTag(nModDoc) => Some(nModDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn fns() -> ~[FnDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| FnTag(FnDoc) => Some(FnDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn consts() -> ~[ConstDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| ConstTag(ConstDoc) => Some(ConstDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn enums() -> ~[EnumDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| EnumTag(EnumDoc) => Some(EnumDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn traits() -> ~[TraitDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| TraitTag(TraitDoc) => Some(TraitDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn impls() -> ~[ImplDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| ImplTag(ImplDoc) => Some(ImplDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn types() -> ~[TyDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| TyTag(TyDoc) => Some(TyDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn structs() -> ~[StructDoc] { |
| do vec::filter_map(self.items) |itemtag| { |
| match *itemtag { |
| StructTag(StructDoc) => Some(StructDoc), |
| _ => None |
| } |
| } |
| } |
| } |
| |
| trait PageUtils { |
| fn mods() -> ~[ModDoc]; |
| fn nmods() -> ~[NmodDoc]; |
| fn fns() -> ~[FnDoc]; |
| fn consts() -> ~[ConstDoc]; |
| fn enums() -> ~[EnumDoc]; |
| fn traits() -> ~[TraitDoc]; |
| fn impls() -> ~[ImplDoc]; |
| fn types() -> ~[TyDoc]; |
| } |
| |
| impl ~[Page]: PageUtils { |
| |
| fn mods() -> ~[ModDoc] { |
| do vec::filter_map(self) |page| { |
| match *page { |
| ItemPage(ModTag(ModDoc)) => Some(ModDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn nmods() -> ~[NmodDoc] { |
| do vec::filter_map(self) |page| { |
| match *page { |
| ItemPage(NmodTag(nModDoc)) => Some(nModDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn fns() -> ~[FnDoc] { |
| do vec::filter_map(self) |page| { |
| match *page { |
| ItemPage(FnTag(FnDoc)) => Some(FnDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn consts() -> ~[ConstDoc] { |
| do vec::filter_map(self) |page| { |
| match *page { |
| ItemPage(ConstTag(ConstDoc)) => Some(ConstDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn enums() -> ~[EnumDoc] { |
| do vec::filter_map(self) |page| { |
| match *page { |
| ItemPage(EnumTag(EnumDoc)) => Some(EnumDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn traits() -> ~[TraitDoc] { |
| do vec::filter_map(self) |page| { |
| match *page { |
| ItemPage(TraitTag(TraitDoc)) => Some(TraitDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn impls() -> ~[ImplDoc] { |
| do vec::filter_map(self) |page| { |
| match *page { |
| ItemPage(ImplTag(ImplDoc)) => Some(ImplDoc), |
| _ => None |
| } |
| } |
| } |
| |
| fn types() -> ~[TyDoc] { |
| do vec::filter_map(self) |page| { |
| match *page { |
| ItemPage(TyTag(TyDoc)) => Some(TyDoc), |
| _ => None |
| } |
| } |
| } |
| } |
| |
| trait Item { |
| pure fn item() -> ItemDoc; |
| } |
| |
| impl ItemTag: Item { |
| pure fn item() -> ItemDoc { |
| match self { |
| doc::ModTag(doc) => doc.item, |
| doc::NmodTag(doc) => doc.item, |
| doc::FnTag(doc) => doc.item, |
| doc::ConstTag(doc) => doc.item, |
| doc::EnumTag(doc) => doc.item, |
| doc::TraitTag(doc) => doc.item, |
| doc::ImplTag(doc) => doc.item, |
| doc::TyTag(doc) => doc.item, |
| doc::StructTag(doc) => doc.item |
| } |
| } |
| } |
| |
| impl SimpleItemDoc: Item { |
| pure fn item() -> ItemDoc { self.item } |
| } |
| |
| impl ModDoc: Item { |
| pure fn item() -> ItemDoc { self.item } |
| } |
| |
| impl NmodDoc: Item { |
| pure fn item() -> ItemDoc { self.item } |
| } |
| |
| impl EnumDoc: Item { |
| pure fn item() -> ItemDoc { self.item } |
| } |
| |
| impl TraitDoc: Item { |
| pure fn item() -> ItemDoc { self.item } |
| } |
| |
| impl ImplDoc: Item { |
| pure fn item() -> ItemDoc { self.item } |
| } |
| |
| impl StructDoc: Item { |
| pure fn item() -> ItemDoc { self.item } |
| } |
| |
| trait ItemUtils { |
| pure fn id() -> AstId; |
| pure fn name() -> ~str; |
| pure fn path() -> ~[~str]; |
| pure fn brief() -> Option<~str>; |
| pure fn desc() -> Option<~str>; |
| pure fn sections() -> ~[Section]; |
| } |
| |
| impl<A:Item> A: ItemUtils { |
| pure fn id() -> AstId { |
| self.item().id |
| } |
| |
| pure fn name() -> ~str { |
| self.item().name |
| } |
| |
| pure fn path() -> ~[~str] { |
| self.item().path |
| } |
| |
| pure fn brief() -> Option<~str> { |
| self.item().brief |
| } |
| |
| pure fn desc() -> Option<~str> { |
| self.item().desc |
| } |
| |
| pure fn sections() -> ~[Section] { |
| self.item().sections |
| } |
| } |