From 09ed245281300cfb84969614ab6e0a0170fd8f84 Mon Sep 17 00:00:00 2001 From: Jamieson Pryor Date: Tue, 9 Jul 2024 15:14:41 -0700 Subject: [PATCH] Fixes field `Static`s that were broken when using `Self`. https://github.com/google/jni-bind/issues/311 PiperOrigin-RevId: 650772628 --- implementation/field_ref.h | 8 ++++++- implementation/static_ref_test.cc | 37 +++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/implementation/field_ref.h b/implementation/field_ref.h index 24c9b9ff..05e1ba51 100644 --- a/implementation/field_ref.h +++ b/implementation/field_ref.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "implementation/class_ref.h" @@ -57,6 +58,8 @@ class FieldRef { using IdT = Id; using FieldSelectionT = FieldSelection; + using SelfIdT = typename IdT::template ChangeIdType; + explicit FieldRef(jclass class_ref, jobject object_ref) : class_ref_(class_ref), object_ref_(object_ref) {} @@ -83,7 +86,10 @@ class FieldRef { }); } - using ReturnProxied = Return_t; + using ReturnProxied = + std::conditional_t, + Return_t >; const auto& SelfVal() { if constexpr (IdT::kIsStatic) { diff --git a/implementation/static_ref_test.cc b/implementation/static_ref_test.cc index 0819cda2..b592ff66 100644 --- a/implementation/static_ref_test.cc +++ b/implementation/static_ref_test.cc @@ -31,6 +31,7 @@ using ::jni::LocalString; using ::jni::Method; using ::jni::Params; using ::jni::Rank; +using ::jni::Self; using ::jni::Static; using ::jni::StaticRef; using ::jni::test::JniTest; @@ -57,7 +58,8 @@ static constexpr Class kClass{ Field{"floatField", jfloat{}}, Field{"doubleField", jdouble{}}, Field{"stringField", jstring{}}, - Field{"classField", Class{"kClass2"}} + Field{"classField", Class{"kClass2"}}, + Field{"selfField", Self{}} }, }; // clang-format on @@ -190,6 +192,25 @@ TEST_F(JniTest, StaticField_ObjectSet) { LocalObject{AdoptLocal{}, Fake()}); } +TEST_F(JniTest, StaticField_SelfGet) { + EXPECT_CALL(*env_, GetStaticFieldID(_, StrEq("selfField"), StrEq("LkClass;"))) + .WillOnce(Return(Fake())); + EXPECT_CALL(*env_, GetStaticObjectField(_, Fake())) + .WillOnce(Return(Fake())); + + jni::LocalObject obj = StaticRef{}["selfField"].Get(); +} + +TEST_F(JniTest, StaticField_SelfSet) { + EXPECT_CALL(*env_, GetStaticFieldID(_, StrEq("selfField"), StrEq("LkClass;"))) + .WillOnce(Return(Fake())); + EXPECT_CALL(*env_, + SetStaticObjectField(_, Fake(), Fake())); + + StaticRef{}["selfField"].Set( + LocalObject{AdoptLocal{}, Fake()}); +} + //////////////////////////////////////////////////////////////////////////////// // Static Methods. //////////////////////////////////////////////////////////////////////////////// @@ -210,6 +231,7 @@ static constexpr Class kMethodClass{ Method{"objectMethod", ::jni::Return{Class{"kClass2"}}}, Method{"rank1ArrayMethod", ::jni::Return{Array{Class{"kClass2"}}}}, Method{"rank2ArrayMethod", ::jni::Return{Array{Class{"kClass2"}, Rank<2>{}}}}, + Method{"selfMethod", ::jni::Return{Self{}}}, Method{"simpleFunc", ::jni::Return{int{}}, Params{jfloat{}}}, Method{"complexFunc", ::jni::Return{float{}}, @@ -248,8 +270,10 @@ TEST_F(JniTest, StaticExerciseAllReturns) { StrEq("()[LkClass2;"))); EXPECT_CALL(*env_, GetStaticMethodID(_, StrEq("rank2ArrayMethod"), StrEq("()[[LkClass2;"))); + EXPECT_CALL(*env_, GetStaticMethodID(_, StrEq("selfMethod"), + StrEq("()LkMethodClass;"))); - EXPECT_CALL(*env_, CallStaticObjectMethodV).Times(4); + EXPECT_CALL(*env_, CallStaticObjectMethodV).Times(5); StaticRef{}("booleanMethod"); StaticRef{}("byteMethod"); @@ -261,10 +285,11 @@ TEST_F(JniTest, StaticExerciseAllReturns) { StaticRef{}("doubleMethod"); StaticRef{}("stringMethod"); - // It would be more complete to exercise all types here. StaticRef{}("objectMethod"); StaticRef{}("rank1ArrayMethod"); StaticRef{}("rank2ArrayMethod"); + + LocalObject self_ret = StaticRef{}("selfMethod"); } // clang-format off @@ -283,6 +308,7 @@ static constexpr Class kMethodClassSingleParam{ Method{"objectMethod", ::jni::Return{}, Params{Class{"kClass2"}}}, Method{"rank1ArrayMethod", ::jni::Return{}, Params{Array{Class{"kClass2"}}}}, Method{"rank2ArrayMethod", ::jni::Return{}, Params{Array{Class{"kClass2"}, Rank<2>{}}}}, + Method{"selfMethod", ::jni::Return{}, Params{Self{}}} }, }; // clang-format on @@ -307,8 +333,10 @@ TEST_F(JniTest, StaticExerciseAllTypesThroughSingleParam) { StrEq("([LkClass2;)V"))); EXPECT_CALL(*env_, GetStaticMethodID(_, StrEq("rank2ArrayMethod"), StrEq("([[LkClass2;)V"))); + EXPECT_CALL(*env_, GetStaticMethodID(_, StrEq("selfMethod"), + StrEq("(LkMethodClassSingleParam;)V"))); - EXPECT_CALL(*env_, CallStaticVoidMethodV).Times(12); + EXPECT_CALL(*env_, CallStaticVoidMethodV).Times(13); StaticRef{}("booleanMethod", jboolean{true}); StaticRef{}("byteMethod", jbyte{1}); @@ -326,6 +354,7 @@ TEST_F(JniTest, StaticExerciseAllTypesThroughSingleParam) { Fake()); StaticRef{}("rank2ArrayMethod", Fake()); + StaticRef{}("selfMethod", Fake()); } TEST_F(JniTest, StaticExerciseComplexSetOfParams) {