Skip to content

Commit 005fd43

Browse files
committed
Move the TypeCollector trait to the ir module
This commit moves the `TypeCollector` trait out from the `codegen` module and into its own submodule in `ir::type_collector`. Additionally, it puts the various `TypeCollector` trait implementations next to the types that each implementation is for.
1 parent 724aa06 commit 005fd43

File tree

8 files changed

+149
-132
lines changed

8 files changed

+149
-132
lines changed

src/codegen/mod.rs

Lines changed: 1 addition & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ use ir::item_kind::ItemKind;
1414
use ir::comp::{CompKind, CompInfo, Field, Method};
1515
use ir::layout::Layout;
1616
use ir::annotations::FieldAccessorKind;
17+
use ir::type_collector::{ItemSet, TypeCollector};
1718

1819
use std::ops;
1920
use std::borrow::Cow;
2021
use std::mem;
21-
use std::collections::BTreeSet;
2222
use std::collections::HashSet;
2323
use std::collections::hash_map::{HashMap, Entry};
2424

@@ -1584,133 +1584,6 @@ impl CodeGenerator for Function {
15841584
}
15851585
}
15861586

1587-
type ItemSet = BTreeSet<ItemId>;
1588-
1589-
trait TypeCollector {
1590-
type Extra;
1591-
1592-
fn collect_types(&self,
1593-
context: &BindgenContext,
1594-
types: &mut ItemSet,
1595-
extra: &Self::Extra);
1596-
}
1597-
1598-
impl TypeCollector for ItemId {
1599-
type Extra = ();
1600-
1601-
fn collect_types(&self,
1602-
context: &BindgenContext,
1603-
types: &mut ItemSet,
1604-
extra: &()) {
1605-
context.resolve_item(*self).collect_types(context, types, extra);
1606-
}
1607-
}
1608-
1609-
impl TypeCollector for Item {
1610-
type Extra = ();
1611-
1612-
fn collect_types(&self,
1613-
context: &BindgenContext,
1614-
types: &mut ItemSet,
1615-
_extra: &()) {
1616-
if self.is_hidden(context) || types.contains(&self.id()) {
1617-
return;
1618-
}
1619-
1620-
match *self.kind() {
1621-
ItemKind::Type(ref ty) => {
1622-
types.insert(self.id());
1623-
if !self.is_opaque(context) {
1624-
ty.collect_types(context, types, self);
1625-
}
1626-
}
1627-
_ => {}, // FIXME.
1628-
}
1629-
}
1630-
}
1631-
1632-
impl TypeCollector for Type {
1633-
type Extra = Item;
1634-
1635-
fn collect_types(&self,
1636-
context: &BindgenContext,
1637-
types: &mut ItemSet,
1638-
item: &Item) {
1639-
match *self.kind() {
1640-
TypeKind::Pointer(inner) |
1641-
TypeKind::Reference(inner) |
1642-
TypeKind::Array(inner, _) |
1643-
TypeKind::TemplateAlias(inner, _) |
1644-
TypeKind::Alias(_, inner) |
1645-
TypeKind::Named(_, Some(inner)) |
1646-
TypeKind::ResolvedTypeRef(inner)
1647-
=> inner.collect_types(context, types, &()),
1648-
1649-
TypeKind::TemplateRef(inner, ref template_args) => {
1650-
inner.collect_types(context, types, &());
1651-
for item in template_args {
1652-
item.collect_types(context, types, &());
1653-
}
1654-
}
1655-
TypeKind::Comp(ref ci) => ci.collect_types(context, types, item),
1656-
TypeKind::Function(ref sig) => {
1657-
sig.collect_types(context, types, item)
1658-
}
1659-
// FIXME: Pending types!
1660-
ref other @ _ => {
1661-
debug!("Ignoring: {:?}", other);
1662-
},
1663-
}
1664-
}
1665-
}
1666-
1667-
impl TypeCollector for FunctionSig {
1668-
type Extra = Item;
1669-
1670-
fn collect_types(&self,
1671-
context: &BindgenContext,
1672-
types: &mut ItemSet,
1673-
_item: &Item) {
1674-
self.return_type().collect_types(context, types, &());
1675-
1676-
for &(_, ty) in self.argument_types() {
1677-
ty.collect_types(context, types, &());
1678-
}
1679-
}
1680-
}
1681-
1682-
impl TypeCollector for CompInfo {
1683-
type Extra = Item;
1684-
1685-
fn collect_types(&self,
1686-
context: &BindgenContext,
1687-
types: &mut ItemSet,
1688-
item: &Item) {
1689-
if let Some(template) = self.specialized_template() {
1690-
template.collect_types(context, types, &());
1691-
}
1692-
1693-
let applicable_template_args = item.applicable_template_args(context);
1694-
for arg in applicable_template_args {
1695-
arg.collect_types(context, types, &());
1696-
}
1697-
1698-
for base in self.base_members() {
1699-
base.collect_types(context, types, &());
1700-
}
1701-
1702-
for field in self.fields() {
1703-
field.ty().collect_types(context, types, &());
1704-
}
1705-
1706-
for ty in self.inner_types() {
1707-
ty.collect_types(context, types, &());
1708-
}
1709-
1710-
// FIXME(emilio): Methods, VTable?
1711-
}
1712-
}
1713-
17141587
pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
17151588
context.gen(|context| {
17161589
let mut result = CodegenResult::new();

src/ir/comp.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use super::context::BindgenContext;
55
use super::layout::Layout;
66
use super::item::{Item, ItemId};
77
use super::ty::{Type, RUST_DERIVE_IN_ARRAY_LIMIT};
8+
use super::type_collector::{ItemSet, TypeCollector};
89
use std::cell::Cell;
910
use std::cmp;
1011
use parse::{ClangItemParser, ParseError};
@@ -804,3 +805,35 @@ impl CompInfo {
804805
})
805806
}
806807
}
808+
809+
impl TypeCollector for CompInfo {
810+
type Extra = Item;
811+
812+
fn collect_types(&self,
813+
context: &BindgenContext,
814+
types: &mut ItemSet,
815+
item: &Item) {
816+
if let Some(template) = self.specialized_template() {
817+
template.collect_types(context, types, &());
818+
}
819+
820+
let applicable_template_args = item.applicable_template_args(context);
821+
for arg in applicable_template_args {
822+
arg.collect_types(context, types, &());
823+
}
824+
825+
for base in self.base_members() {
826+
base.collect_types(context, types, &());
827+
}
828+
829+
for field in self.fields() {
830+
field.ty().collect_types(context, types, &());
831+
}
832+
833+
for ty in self.inner_types() {
834+
ty.collect_types(context, types, &());
835+
}
836+
837+
// FIXME(emilio): Methods, VTable?
838+
}
839+
}

src/ir/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ enum TypeKey {
3232
// context.
3333
struct GenContext<'ctx>(ExtCtxt<'ctx>);
3434

35-
impl<'ctx> fmt::Debug for GenContext <'ctx> {
35+
impl<'ctx> fmt::Debug for GenContext<'ctx> {
3636
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
3737
write!(fmt, "GenContext {{ ... }}")
3838
}

src/ir/function.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
//! Intermediate representation for C/C++ functions and methods.
22
3+
use super::context::BindgenContext;
34
use super::item::{Item, ItemId};
45
use super::ty::TypeKind;
5-
use super::context::BindgenContext;
6+
use super::type_collector::{ItemSet, TypeCollector};
67
use syntax::abi;
78
use clang;
89
use clangll::Enum_CXCallingConv;
@@ -246,3 +247,18 @@ impl ClangSubItemParser for Function {
246247
Ok(ParseResult::New(function, Some(cursor)))
247248
}
248249
}
250+
251+
impl TypeCollector for FunctionSig {
252+
type Extra = Item;
253+
254+
fn collect_types(&self,
255+
context: &BindgenContext,
256+
types: &mut ItemSet,
257+
_item: &Item) {
258+
self.return_type().collect_types(context, types, &());
259+
260+
for &(_, ty) in self.argument_types() {
261+
ty.collect_types(context, types, &());
262+
}
263+
}
264+
}

src/ir/item.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use regex::Regex;
44
use super::context::BindgenContext;
55
use super::item_kind::ItemKind;
66
use super::ty::{Type, TypeKind};
7+
use super::type_collector::{ItemSet, TypeCollector};
78
use super::function::Function;
89
use super::module::Module;
910
use super::annotations::Annotations;
@@ -76,6 +77,40 @@ impl ItemCanonicalPath for ItemId {
7677
}
7778
}
7879

80+
impl TypeCollector for ItemId {
81+
type Extra = ();
82+
83+
fn collect_types(&self,
84+
context: &BindgenContext,
85+
types: &mut ItemSet,
86+
extra: &()) {
87+
context.resolve_item(*self).collect_types(context, types, extra);
88+
}
89+
}
90+
91+
impl TypeCollector for Item {
92+
type Extra = ();
93+
94+
fn collect_types(&self,
95+
context: &BindgenContext,
96+
types: &mut ItemSet,
97+
_extra: &()) {
98+
if self.is_hidden(context) || types.contains(&self.id()) {
99+
return;
100+
}
101+
102+
match *self.kind() {
103+
ItemKind::Type(ref ty) => {
104+
types.insert(self.id());
105+
if !self.is_opaque(context) {
106+
ty.collect_types(context, types, self);
107+
}
108+
}
109+
_ => {}, // FIXME.
110+
}
111+
}
112+
}
113+
79114
/// An item is the base of the bindgen representation, it can be either a
80115
/// module, a type, a function, or a variable (see `ItemKind` for more
81116
/// information).
@@ -566,12 +601,12 @@ impl Item {
566601
static ref RE_ENDS_WITH_BINDGEN_TY: Regex = Regex::new(r"_bindgen_ty(_\d+)+$").unwrap();
567602
static ref RE_ENDS_WITH_BINDGEN_MOD: Regex = Regex::new(r"_bindgen_mod(_\d+)+$").unwrap();
568603
}
569-
604+
570605
let (re, kind) = match *self.kind() {
571606
ItemKind::Module(..) => (&*RE_ENDS_WITH_BINDGEN_MOD, "mod"),
572607
_ => (&*RE_ENDS_WITH_BINDGEN_TY, "ty"),
573608
};
574-
609+
575610
let parent_name = parent_name.and_then(|n| if n.is_empty() { None } else { Some(n) });
576611
match (parent_name, base_name) {
577612
(Some(parent), Some(base)) => format!("{}_{}", parent, base),

src/ir/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ pub mod item_kind;
1414
pub mod layout;
1515
pub mod module;
1616
pub mod ty;
17+
pub mod type_collector;
1718
pub mod var;

src/ir/ty.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::item::{Item, ItemId};
77
use super::int::IntKind;
88
use super::layout::Layout;
99
use super::context::BindgenContext;
10+
use super::type_collector::{ItemSet, TypeCollector};
1011
use parse::{ClangItemParser, ParseResult, ParseError};
1112
use clang::{self, Cursor};
1213

@@ -709,3 +710,38 @@ impl Type {
709710
Ok(ParseResult::New(ty, Some(cursor.canonical())))
710711
}
711712
}
713+
714+
impl TypeCollector for Type {
715+
type Extra = Item;
716+
717+
fn collect_types(&self,
718+
context: &BindgenContext,
719+
types: &mut ItemSet,
720+
item: &Item) {
721+
match *self.kind() {
722+
TypeKind::Pointer(inner) |
723+
TypeKind::Reference(inner) |
724+
TypeKind::Array(inner, _) |
725+
TypeKind::TemplateAlias(inner, _) |
726+
TypeKind::Alias(_, inner) |
727+
TypeKind::Named(_, Some(inner)) |
728+
TypeKind::ResolvedTypeRef(inner)
729+
=> inner.collect_types(context, types, &()),
730+
731+
TypeKind::TemplateRef(inner, ref template_args) => {
732+
inner.collect_types(context, types, &());
733+
for item in template_args {
734+
item.collect_types(context, types, &());
735+
}
736+
}
737+
TypeKind::Comp(ref ci) => ci.collect_types(context, types, item),
738+
TypeKind::Function(ref sig) => {
739+
sig.collect_types(context, types, item)
740+
}
741+
// FIXME: Pending types!
742+
ref other @ _ => {
743+
debug!("Ignoring: {:?}", other);
744+
},
745+
}
746+
}
747+
}

src/ir/type_collector.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//! Collecting type items.
2+
3+
use std::collections::BTreeSet;
4+
use super::context::BindgenContext;
5+
use super::item::ItemId;
6+
7+
/// A set of items.
8+
pub type ItemSet = BTreeSet<ItemId>;
9+
10+
/// Collect all the type items referenced by this item.
11+
pub trait TypeCollector {
12+
/// If a particular type needs extra information beyond what it has in
13+
/// `self` and `context` to find its referenced type items, its
14+
/// implementation can define this associated type, forcing callers to pass
15+
/// the needed information through.
16+
type Extra;
17+
18+
/// Add each type item referenced by `self` into the `types` set.
19+
fn collect_types(&self,
20+
context: &BindgenContext,
21+
types: &mut ItemSet,
22+
extra: &Self::Extra);
23+
}

0 commit comments

Comments
 (0)