summaryrefslogtreecommitdiff
path: root/libbindgen/src/codegen
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2016-12-01 13:16:16 -0800
committerNick Fitzgerald <fitzgen@gmail.com>2016-12-02 11:10:40 -0800
commit8091fd641b9692007bbb85d3bec37afc426b897d (patch)
tree439dc983b9d3b55b1eebe33fba01a26fbe75b67b /libbindgen/src/codegen
parentd45db65fecfb973c10b4a1519571eeda50cb625b (diff)
Use the generated root module via a relative path
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
Diffstat (limited to 'libbindgen/src/codegen')
-rw-r--r--libbindgen/src/codegen/mod.rs32
1 files changed, 27 insertions, 5 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs
index ad9ac2de..7fa76d56 100644
--- a/libbindgen/src/codegen/mod.rs
+++ b/libbindgen/src/codegen/mod.rs
@@ -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;
@@ -22,6 +22,7 @@ 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;
@@ -29,12 +30,33 @@ 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");
+ assert!(module.is_module());
+
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_));
+
+ 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 {
@@ -286,7 +308,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);
});