By checking the recursion depth in the crate we are currently parsing,
we can decide on the right module directory to find submodules in. The
added `mod_2018` test fails without the changes to `parser.rs`.
This commit is contained in:
Vincent Tavernier 2020-04-15 11:48:59 +02:00
parent ea6ea24740
commit 60d60aaf0d
14 changed files with 163 additions and 6 deletions

View File

@ -238,6 +238,10 @@ impl<'a> Parser<'a> {
}
fn parse_mod(&mut self, pkg: &PackageRef, mod_path: &FilePath) -> Result<(), Error> {
self.parse_mod_depth(pkg, mod_path, 0)
}
fn parse_mod_depth(&mut self, pkg: &PackageRef, mod_path: &FilePath, depth: usize) -> Result<(), Error> {
let mod_parsed = {
let owned_mod_path = mod_path.to_path_buf();
@ -265,9 +269,17 @@ impl<'a> Parser<'a> {
self.cache_src.get(&owned_mod_path).unwrap().clone()
};
let mod_dir = mod_path.parent().unwrap();
// Compute module directory according to Rust 2018 rules
let mod_dir_2018;
self.process_mod(pkg, mod_dir, &mod_parsed)
let mod_dir = if depth == 0 {
mod_path.parent().unwrap()
} else {
mod_dir_2018 = mod_path.parent().unwrap().join(mod_path.file_stem().unwrap());
&mod_dir_2018
};
self.process_mod(pkg, &mod_dir, &mod_parsed, depth)
}
fn process_mod(
@ -275,6 +287,7 @@ impl<'a> Parser<'a> {
pkg: &PackageRef,
mod_dir: &FilePath,
items: &[syn::Item],
depth: usize,
) -> Result<(), Error> {
self.out.load_syn_crate_mod(
&self.config,
@ -297,15 +310,15 @@ impl<'a> Parser<'a> {
}
if let Some((_, ref inline_items)) = item.content {
self.process_mod(pkg, &mod_dir.join(&next_mod_name), inline_items)?;
self.process_mod(pkg, &mod_dir.join(&next_mod_name), inline_items, depth)?;
} else {
let next_mod_path1 = mod_dir.join(next_mod_name.clone() + ".rs");
let next_mod_path2 = mod_dir.join(next_mod_name.clone()).join("mod.rs");
if next_mod_path1.exists() {
self.parse_mod(pkg, next_mod_path1.as_path())?;
self.parse_mod_depth(pkg, next_mod_path1.as_path(), depth + 1)?;
} else if next_mod_path2.exists() {
self.parse_mod(pkg, next_mod_path2.as_path())?;
self.parse_mod_depth(pkg, next_mod_path2.as_path(), depth + 1)?;
} else {
// Last chance to find a module path
let mut path_attr_found = false;
@ -316,7 +329,7 @@ impl<'a> Parser<'a> {
})) => match lit {
syn::Lit::Str(ref path_lit) if path.is_ident("path") => {
path_attr_found = true;
self.parse_mod(pkg, &mod_dir.join(path_lit.value()))?;
self.parse_mod_depth(pkg, &mod_dir.join(path_lit.value()), depth + 1)?;
break;
}
_ => (),

View File

@ -0,0 +1,12 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define EXPORT_ME_TOO 42
typedef struct ExportMe {
uint64_t val;
} ExportMe;
void export_me(ExportMe *val);

View File

@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define EXPORT_ME_TOO 42
typedef struct ExportMe {
uint64_t val;
} ExportMe;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void export_me(ExportMe *val);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View File

@ -0,0 +1,12 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define EXPORT_ME_TOO 42
typedef struct {
uint64_t val;
} ExportMe;
void export_me(ExportMe *val);

View File

@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define EXPORT_ME_TOO 42
typedef struct {
uint64_t val;
} ExportMe;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void export_me(ExportMe *val);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View File

@ -0,0 +1,16 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <new>
static const uint8_t EXPORT_ME_TOO = 42;
struct ExportMe {
uint64_t val;
};
extern "C" {
void export_me(ExportMe *val);
} // extern "C"

View File

@ -0,0 +1,12 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define EXPORT_ME_TOO 42
struct ExportMe {
uint64_t val;
};
void export_me(struct ExportMe *val);

View File

@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define EXPORT_ME_TOO 42
struct ExportMe {
uint64_t val;
};
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void export_me(struct ExportMe *val);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

6
tests/rust/mod_2018/Cargo.lock generated Normal file
View File

@ -0,0 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "mod_2018"
version = "0.1.0"

View File

@ -0,0 +1,8 @@
[package]
name = "mod_2018"
version = "0.1.0"
authors = ["cbindgen"]
[lib]
name = "mod_2018"
crate-type = ["lib", "dylib"]

View File

@ -0,0 +1,2 @@
[parse]
parse_deps = false

View File

@ -0,0 +1 @@
pub mod nested;

View File

@ -0,0 +1 @@
pub mod other;

View File

@ -0,0 +1,14 @@
#[repr(C)]
pub struct ExportMe {
val: u64
}
#[repr(C)]
pub struct DoNotExportMe {
val: u64
}
pub const EXPORT_ME_TOO: u8 = 0x2a;
#[no_mangle]
pub unsafe extern "C" fn export_me(val: *mut ExportMe) { }