From b04aa7e6991bc9d12392d47cffea077aa56d8b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 1 May 2020 04:24:07 +0200 Subject: [PATCH] parser: Introduce cbindgen:ignore comment annotation, to allow ignoring items or modules. --- docs.md | 14 ++++++++- src/bindgen/utilities.rs | 38 +++++++++++++++++-------- tests/expectations/both/ignore.c | 6 ++++ tests/expectations/both/ignore.compat.c | 14 +++++++++ tests/expectations/ignore.c | 6 ++++ tests/expectations/ignore.compat.c | 14 +++++++++ tests/expectations/ignore.cpp | 10 +++++++ tests/expectations/tag/ignore.c | 6 ++++ tests/expectations/tag/ignore.compat.c | 14 +++++++++ tests/rust/ignore.rs | 12 ++++++++ 10 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 tests/expectations/both/ignore.c create mode 100644 tests/expectations/both/ignore.compat.c create mode 100644 tests/expectations/ignore.c create mode 100644 tests/expectations/ignore.compat.c create mode 100644 tests/expectations/ignore.cpp create mode 100644 tests/expectations/tag/ignore.c create mode 100644 tests/expectations/tag/ignore.compat.c create mode 100644 tests/rust/ignore.rs diff --git a/docs.md b/docs.md index 3995dbc..d61540c 100644 --- a/docs.md +++ b/docs.md @@ -235,6 +235,19 @@ An annotation may be a bool, string (no quotes), or list of strings. If just the Most annotations are just local overrides for identical settings in the cbindgen.toml, but a few are unique because they don't make sense in a global context. The set of supported annotation are as follows: +### Ignore annotation + +cbindgen will automatically ignore any `#[test]` or `#[cfg(test)]` item it +finds. You can manually ignore other stuff with the `ignore` annotation +attribute: + +```rust +pub mod my_interesting_mod; + +/// cbindgen:ignore +pub mod my_uninteresting_mod; // This won't be scanned by cbindgen. +``` + ### Struct Annotations * field-names=\[field1, field2, ...\] -- sets the names of all the fields in the output struct. These names will be output verbatim, and are not eligible for renaming. @@ -335,7 +348,6 @@ Given configuration in the cbindgen.toml, `cbindgen` can generate these attribut This is controlled by the `swift_name_macro` option in the cbindgen.toml. - ## cbindgen.toml Most configuration happens through your cbindgen.toml file. Every value has a default (that is usually reasonable), so you can start with an empty cbindgen.toml and tweak it until you like the output you're getting. diff --git a/src/bindgen/utilities.rs b/src/bindgen/utilities.rs index fffb4c6..c81efc1 100644 --- a/src/bindgen/utilities.rs +++ b/src/bindgen/utilities.rs @@ -71,26 +71,40 @@ impl SynItemFnHelpers for syn::ImplItemMethod { } } +/// Returns whether this attribute causes us to skip at item. This basically +/// checks for `#[cfg(test)]`, `#[test]`, `/// cbindgen::ignore` and +/// variations thereof. fn is_skip_item_attr(attr: &syn::Meta) -> bool { match *attr { syn::Meta::Path(ref path) => { - if path.is_ident("test") { - return true; - } + // TODO(emilio): It'd be great if rustc allowed us to use a syntax + // like `#[cbindgen::ignore]` or such. + path.is_ident("test") } syn::Meta::List(ref list) => { - if list.path.is_ident("cfg") { - return list.nested.iter().any(|nested| match *nested { - syn::NestedMeta::Meta(ref meta) => { - return is_skip_item_attr(meta); - } - syn::NestedMeta::Lit(..) => false, - }); + if !list.path.is_ident("cfg") { + return false; } + list.nested.iter().any(|nested| match *nested { + syn::NestedMeta::Meta(ref meta) => { + return is_skip_item_attr(meta); + } + syn::NestedMeta::Lit(..) => false, + }) + } + syn::Meta::NameValue(ref name_value) => { + if name_value.path.is_ident("doc") { + if let syn::Lit::Str(ref content) = name_value.lit { + // FIXME(emilio): Maybe should use the general annotation + // mechanism, but it seems overkill for this. + if content.value().trim() == "cbindgen:ignore" { + return true; + } + } + } + false } - syn::Meta::NameValue(..) => {} } - false } pub trait SynAttributeHelpers { diff --git a/tests/expectations/both/ignore.c b/tests/expectations/both/ignore.c new file mode 100644 index 0000000..8e7da96 --- /dev/null +++ b/tests/expectations/both/ignore.c @@ -0,0 +1,6 @@ +#include +#include +#include +#include + +void no_ignore_root(void); diff --git a/tests/expectations/both/ignore.compat.c b/tests/expectations/both/ignore.compat.c new file mode 100644 index 0000000..a99dcee --- /dev/null +++ b/tests/expectations/both/ignore.compat.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void no_ignore_root(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/ignore.c b/tests/expectations/ignore.c new file mode 100644 index 0000000..8e7da96 --- /dev/null +++ b/tests/expectations/ignore.c @@ -0,0 +1,6 @@ +#include +#include +#include +#include + +void no_ignore_root(void); diff --git a/tests/expectations/ignore.compat.c b/tests/expectations/ignore.compat.c new file mode 100644 index 0000000..a99dcee --- /dev/null +++ b/tests/expectations/ignore.compat.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void no_ignore_root(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/ignore.cpp b/tests/expectations/ignore.cpp new file mode 100644 index 0000000..6993ea7 --- /dev/null +++ b/tests/expectations/ignore.cpp @@ -0,0 +1,10 @@ +#include +#include +#include +#include + +extern "C" { + +void no_ignore_root(); + +} // extern "C" diff --git a/tests/expectations/tag/ignore.c b/tests/expectations/tag/ignore.c new file mode 100644 index 0000000..8e7da96 --- /dev/null +++ b/tests/expectations/tag/ignore.c @@ -0,0 +1,6 @@ +#include +#include +#include +#include + +void no_ignore_root(void); diff --git a/tests/expectations/tag/ignore.compat.c b/tests/expectations/tag/ignore.compat.c new file mode 100644 index 0000000..a99dcee --- /dev/null +++ b/tests/expectations/tag/ignore.compat.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void no_ignore_root(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/rust/ignore.rs b/tests/rust/ignore.rs new file mode 100644 index 0000000..54ade32 --- /dev/null +++ b/tests/rust/ignore.rs @@ -0,0 +1,12 @@ +/// cbindgen:ignore +#[no_mangle] +pub extern "C" fn root() {} + +/// cbindgen:ignore +/// +/// Something else. +#[no_mangle] +pub extern "C" fn another_root() {} + +#[no_mangle] +pub extern "C" fn no_ignore_root() {}