Repository: Dushistov/flapigen-rs (Rust)

Issue:
Enhancement: add support for `protected` for functions (in Java)
Hey,

I'm trying to implement a workaround for #329 and I settled on something like this:
```java
foreign_class!(class FetchOptions {
    self_type FetchOptions;
    constructor FetchOptions::new() -> FetchOptions;

    fn FetchOptions::prefetch(&mut self, prefetch: PrefetchOption); alias __prefetch;
   
    foreign_code r#"
    public final FetchOptions prefetch(PrefetchOption prefetch) {
        this.__prefetch(prefetch);
        return this;
    }
"#;
});
```

Though my problem is that __prefetch is generated as public. I saw in the flapigen sources that there are `private` and `protected` keywords though they are not implemented for Java it seems? Is this something that's hard to add?

Thanks,
Tom


Discussion:
> keywords though they are not implemented for Java it seems?

`private` keyword should works just fine, `protected` is not implemented.
I suppose I missed that there is such keyword in Java.
How do I mark a function as private? I haven't managed to figure it out (tried a few combinations). I only managed to get it to work for constructors.

Thanks!
Nevermind, I take it back. I haven't tried `private fn` it seems. I tried omitting the fn, like is done for constructors, tried putting it after the function and etc but not this. :man_facepalming: 

It works, sorry for the noise.
Thanks a lot!
> Nevermind, I take it back.

You misunderstanding  hint me that I actually do not document this,
should be fixed now:

https://dushistov.github.io/flapigen-rs/foreign-class.html#access-modifiers
Thanks a lot, makes the difference! I'm sorry again for opening so many tickets, it's just such a great project, so I want to help, even if my ability is limited to only reporting issues I'm encountering. Thanks a lot for this!



Patch:
diff --git a/macroslib/src/code_parse.rs b/macroslib/src/code_parse.rs
index 002f7fbb..0d7965dc 100644
--- a/macroslib/src/code_parse.rs
+++ b/macroslib/src/code_parse.rs
@@ -188,7 +188,7 @@ fn parse_doc_comments(input: ParseStream) -> syn::Result<Vec<String>> {
     Ok(doc_comments)
 }
 
-fn do_parse_foreigner_class(lang: Language, input: ParseStream) -> syn::Result<ForeignClassInfo> {
+fn do_parse_foreigner_class(_lang: Language, input: ParseStream) -> syn::Result<ForeignClassInfo> {
     let Attrs {
         doc_comments: class_doc_comments,
         derive_list,
@@ -231,12 +231,12 @@ fn do_parse_foreigner_class(lang: Language, input: ParseStream) -> syn::Result<F
         } else {
             MethodAccess::Public
         };
-        if let Language::Cpp = lang {
-            if content.peek(kw::protected) {
-                content.parse::<kw::protected>()?;
-                access = MethodAccess::Protected;
-            }
+
+        if content.peek(kw::protected) {
+            content.parse::<kw::protected>()?;
+            access = MethodAccess::Protected;
         }
+
         let (func_type_name, func_type_name_span): (String, Span) = if content.peek(Token![fn]) {
             let token = content.parse::<Token![fn]>()?;
             (FN.into(), token.span())
diff --git a/macroslib/src/java_jni/fclass.rs b/macroslib/src/java_jni/fclass.rs
index b00b18a0..5ec8b01e 100644
--- a/macroslib/src/java_jni/fclass.rs
+++ b/macroslib/src/java_jni/fclass.rs
@@ -134,7 +134,7 @@ public final class {class_name} {{"#,
         let method_access = match method.access {
             MethodAccess::Private => "private",
             MethodAccess::Public => "public",
-            MethodAccess::Protected => unreachable!(),
+            MethodAccess::Protected => "protected",
         };
         let conv_code_flags = match method.variant {
             MethodVariant::StaticMethod => java_code::ArgsFormatFlags::INTERNAL,


Test patch:
diff --git a/macroslib/tests/expectations/access.cpp b/macroslib/tests/expectations/access.cpp
new file mode 100644
index 00000000..bdf600a4
--- /dev/null
+++ b/macroslib/tests/expectations/access.cpp
@@ -0,0 +1,18 @@
+r#"private:
+
+    FooWrapper(int32_t a0) noexcept
+    {
+
+        this->self_ = private_Foo_from_int(a0);
+        if (this->self_ == nullptr) {
+            std::abort();
+        }
+    }
+
+    static void private_f() noexcept;
+public:
+
+    static void public_f() noexcept;
+protected:
+
+    static void protected_f() noexcept;"#;
diff --git a/macroslib/tests/expectations/access.java b/macroslib/tests/expectations/access.java
new file mode 100644
index 00000000..f73fd119
--- /dev/null
+++ b/macroslib/tests/expectations/access.java
@@ -0,0 +1,5 @@
+r#"private static native void private_f()"#;
+r#"public static native void public_f()"#;
+r#"protected static native void protected_f()"#;
+r#"private Foo(int a0)"#;
+r#"public Foo()"#;
diff --git a/macroslib/tests/expectations/access.rs b/macroslib/tests/expectations/access.rs
new file mode 100644
index 00000000..23c551a8
--- /dev/null
+++ b/macroslib/tests/expectations/access.rs
@@ -0,0 +1,10 @@
+foreign_class!(
+    class Foo {
+        self_type Foo;
+        constructor Foo::new() -> Foo;
+        private constructor Foo::from_int(_: i32) -> Foo;
+        private fn Foo::private_f();
+        fn Foo::public_f();
+        protected fn Foo::protected_f();
+    }
+);
diff --git a/macroslib/tests/expectations/tests.list b/macroslib/tests/expectations/tests.list
index 53ec72f4..53cc7fd4 100644
--- a/macroslib/tests/expectations/tests.list
+++ b/macroslib/tests/expectations/tests.list
@@ -57,4 +57,5 @@ callback_with_several_traits
 reachability_fence_java
 inline_dyn
 fenum_with_comments
-cpp_plain_class
\ No newline at end of file
+cpp_plain_class
+access
\ No newline at end of file