summaryrefslogtreecommitdiff
path: root/libbindgen/src/codegen/mod.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-12-02 11:11:11 -0800
committerGitHub <noreply@github.com>2016-12-02 11:11:11 -0800
commitb8014b1034ac486d3169e71d58e6387f8b1d25f1 (patch)
treeaa5ac6aeb974106681a7cec128d6d331b6dff16e /libbindgen/src/codegen/mod.rs
parent9fcaf776aca28f605193f4d072722c5fcd56cb06 (diff)
parent8091fd641b9692007bbb85d3bec37afc426b897d (diff)
Auto merge of #309 - fitzgen:use-root-relative, r=emilio
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 r? @emilio
Diffstat (limited to 'libbindgen/src/codegen/mod.rs')
-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);
});