Skip to content

Commit

Permalink
Use the generated root module via a relative path
Browse files Browse the repository at this point in the history
We previously generated uses of the root module with absolute paths:

    use root;

However this only works if the generated bindings are the root of the
crate. If they were in some submodule then that path would not be
valid. They are now generated relative to the current module, like this:

    use self::super::super::root;

Fixes #96
  • Loading branch information
fitzgen committed Dec 1, 2016
1 parent d45db65 commit 512f4a6
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 28 deletions.
31 changes: 26 additions & 5 deletions libbindgen/src/codegen/mod.rs
Expand Up @@ -9,7 +9,7 @@ use ir::context::{BindgenContext, ItemId};
use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
use ir::function::{Function, FunctionSig};
use ir::int::IntKind;
use ir::item::{Item, ItemCanonicalName, ItemCanonicalPath};
use ir::item::{Item, ItemAncestors, ItemCanonicalName, ItemCanonicalPath};
use ir::item_kind::ItemKind;
use ir::layout::Layout;
use ir::module::Module;
Expand All @@ -22,19 +22,40 @@ use std::borrow::Cow;
use std::collections::HashSet;
use std::collections::hash_map::{Entry, HashMap};
use std::fmt::Write;
use std::iter;
use std::mem;
use std::ops;
use syntax::abi::Abi;
use syntax::ast;
use syntax::codemap::{Span, respan};
use syntax::ptr::P;

fn root_import(ctx: &BindgenContext) -> P<ast::Item> {
fn root_import(ctx: &BindgenContext, module: &Item) -> P<ast::Item> {
assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up");

let root = ctx.root_module().canonical_name(ctx);
let root_ident = ctx.rust_ident(&root);
quote_item!(ctx.ext_cx(), #[allow(unused_imports)] use $root_ident;)
.unwrap()

let super_ = aster::AstBuilder::new().id("super");
let supers = module
.ancestors(ctx)
.filter(|id| ctx.resolve_item(*id).is_module())
.map(|_| super_.clone())
.chain(iter::once(super_.clone()));

let self_ = iter::once(aster::AstBuilder::new().id("self"));
let root_ident = iter::once(root_ident);

let path = self_.chain(supers).chain(root_ident);

let use_root = aster::AstBuilder::new()
.item()
.use_()
.ids(path)
.build()
.build();

quote_item!(ctx.ext_cx(), #[allow(unused_imports)] $use_root).unwrap()
}

struct CodegenResult {
Expand Down Expand Up @@ -286,7 +307,7 @@ impl CodeGenerator for Module {

let mut found_any = false;
let inner_items = result.inner(|result| {
result.push(root_import(ctx));
result.push(root_import(ctx, item));
codegen_self(result, &mut found_any);
});

Expand Down
Expand Up @@ -6,10 +6,10 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
pub mod foo {
#[allow(unused_imports)]
use root;
use self::super::super::root;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Bar {
Expand All @@ -27,7 +27,7 @@ pub mod root {
}
pub mod bar {
#[allow(unused_imports)]
use root;
use self::super::super::root;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Foo {
Expand Down
Expand Up @@ -6,5 +6,5 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
}
Expand Up @@ -6,15 +6,15 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
pub mod foo {
#[allow(unused_imports)]
use root;
use self::super::super::root;
pub const FOO: ::std::os::raw::c_int = 4;
}
pub mod bar {
#[allow(unused_imports)]
use root;
use self::super::super::root;
pub const FOO: ::std::os::raw::c_int = 5;
}
}
2 changes: 1 addition & 1 deletion libbindgen/tests/expectations/tests/module-whitelisted.rs
Expand Up @@ -6,7 +6,7 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Test {
Expand Down
8 changes: 4 additions & 4 deletions libbindgen/tests/expectations/tests/namespace.rs
Expand Up @@ -6,14 +6,14 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
extern "C" {
#[link_name = "_Z9top_levelv"]
pub fn top_level();
}
pub mod whatever {
#[allow(unused_imports)]
use root;
use self::super::super::root;
pub type whatever_int_t = ::std::os::raw::c_int;
extern "C" {
#[link_name = "_ZN8whatever11in_whateverEv"]
Expand All @@ -22,7 +22,7 @@ pub mod root {
}
pub mod _bindgen_mod_id_13 {
#[allow(unused_imports)]
use root;
use self::super::super::root;
extern "C" {
#[link_name = "_ZN12_GLOBAL__N_13fooEv"]
pub fn foo();
Expand Down Expand Up @@ -51,7 +51,7 @@ pub mod root {
}
pub mod w {
#[allow(unused_imports)]
use root;
use self::super::super::root;
pub type whatever_int_t = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Debug)]
Expand Down
Expand Up @@ -6,10 +6,10 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
pub mod foo {
#[allow(unused_imports)]
use root;
use self::super::super::root;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Bar {
Expand Down
Expand Up @@ -6,13 +6,13 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
pub mod JS {
#[allow(unused_imports)]
use root;
use self::super::super::root;
pub mod detail {
#[allow(unused_imports)]
use root;
use self::super::super::super::root;
pub type Wrapped<T> = T;
}
#[repr(C)]
Expand Down
Expand Up @@ -6,13 +6,13 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
pub mod outer {
#[allow(unused_imports)]
use root;
use self::super::super::root;
pub mod inner {
#[allow(unused_imports)]
use root;
use self::super::super::super::root;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Helper {
Expand Down
6 changes: 3 additions & 3 deletions libbindgen/tests/expectations/tests/whitelist-namespaces.rs
Expand Up @@ -6,13 +6,13 @@

pub mod root {
#[allow(unused_imports)]
use root;
use self::super::root;
pub mod outer {
#[allow(unused_imports)]
use root;
use self::super::super::root;
pub mod inner {
#[allow(unused_imports)]
use root;
use self::super::super::super::root;
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Helper {
Expand Down

0 comments on commit 512f4a6

Please sign in to comment.