Repository: dtolnay/cxx (language: rust)

Issue:
Pass through `#[doc(hidden)]` attribute
Since cxx is so awesome at wrapping C++, it is nice to be able to export the interface directly on the rust side, but sometimes it is preferable to hide certain functions that are used directly by a custom `impl MyCxxType`. Since all functions are public they all by default want to show up in the docs which I find myself using a lot given proc macro support in IDEs is still early.


Discussion / hints:

Fix patch:
diff --git a/syntax/attrs.rs b/syntax/attrs.rs
index fa6c80975..69ce7580c 100644
--- a/syntax/attrs.rs
+++ b/syntax/attrs.rs
@@ -5,7 +5,7 @@ use crate::syntax::{Derive, Doc, ForeignName};
 use proc_macro2::{Ident, TokenStream};
 use quote::ToTokens;
 use syn::parse::{Nothing, Parse, ParseStream, Parser as _};
-use syn::{Attribute, Error, LitStr, Path, Result, Token};
+use syn::{parenthesized, token, Attribute, Error, LitStr, Path, Result, Token};
 
 // Intended usage:
 //
@@ -46,9 +46,12 @@ pub fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Othe
     for attr in attrs {
         if attr.path.is_ident("doc") {
             match parse_doc_attribute.parse2(attr.tokens.clone()) {
-                Ok(lit) => {
+                Ok(attr) => {
                     if let Some(doc) = &mut parser.doc {
-                        doc.push(lit);
+                        match attr {
+                            DocAttribute::Doc(lit) => doc.push(lit),
+                            DocAttribute::Hidden => doc.hidden = true,
+                        }
                         continue;
                     }
                 }
@@ -156,10 +159,29 @@ pub fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Othe
     OtherAttrs(passthrough_attrs)
 }
 
-fn parse_doc_attribute(input: ParseStream) -> Result<LitStr> {
-    input.parse::<Token![=]>()?;
-    let lit: LitStr = input.parse()?;
-    Ok(lit)
+enum DocAttribute {
+    Doc(LitStr),
+    Hidden,
+}
+
+mod kw {
+    syn::custom_keyword!(hidden);
+}
+
+fn parse_doc_attribute(input: ParseStream) -> Result<DocAttribute> {
+    let lookahead = input.lookahead1();
+    if lookahead.peek(Token![=]) {
+        input.parse::<Token![=]>()?;
+        let lit: LitStr = input.parse()?;
+        Ok(DocAttribute::Doc(lit))
+    } else if lookahead.peek(token::Paren) {
+        let content;
+        parenthesized!(content in input);
+        content.parse::<kw::hidden>()?;
+        Ok(DocAttribute::Hidden)
+    } else {
+        Err(lookahead.error())
+    }
 }
 
 fn parse_derive_attribute(cx: &mut Errors, input: ParseStream) -> Result<Vec<Derive>> {
diff --git a/syntax/doc.rs b/syntax/doc.rs
index cd764facb..55a1de1ac 100644
--- a/syntax/doc.rs
+++ b/syntax/doc.rs
@@ -3,12 +3,14 @@ use quote::{quote, ToTokens};
 use syn::LitStr;
 
 pub struct Doc {
+    pub(crate) hidden: bool,
     fragments: Vec<LitStr>,
 }
 
 impl Doc {
     pub fn new() -> Self {
         Doc {
+            hidden: false,
             fragments: Vec::new(),
         }
     }
@@ -34,8 +36,9 @@ impl Doc {
 impl ToTokens for Doc {
     fn to_tokens(&self, tokens: &mut TokenStream) {
         let fragments = &self.fragments;
-        tokens.extend(quote! {
-            #(#[doc = #fragments])*
-        });
+        tokens.extend(quote! { #(#[doc = #fragments])* });
+        if self.hidden {
+            tokens.extend(quote! { #[doc(hidden)] });
+        }
     }
 }


Test patch: