Skip to content

Commit

Permalink
Add Self class which can refer to the containing class's Id.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 561114658
  • Loading branch information
jwhpryor authored and copybara-github committed Aug 29, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 3c3010e commit 7649b1a
Showing 16 changed files with 417 additions and 18 deletions.
2 changes: 2 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ cc_library(
"//implementation:corpus",
"//implementation:corpus_tag",
"//implementation:field",
"//implementation:forward_declarations",
"//implementation:global_class_loader",
"//implementation:global_object",
"//implementation:global_string",
@@ -56,6 +57,7 @@ cc_library(
"//implementation:promotion_mechanics",
"//implementation:return",
"//implementation:selector_static_info",
"//implementation:self",
"//implementation:static",
"//implementation:static_ref",
"//implementation:string_ref",
23 changes: 23 additions & 0 deletions implementation/BUILD
Original file line number Diff line number Diff line change
@@ -397,6 +397,7 @@ cc_library(
":no_idx",
":proxy_convenience_aliases",
":selector_static_info",
":self",
":signature",
"//metaprogramming:replace_string",
],
@@ -641,11 +642,13 @@ cc_library(
deps = [
":class_loader",
":class_ref",
":default_class_loader",
":id_type",
":jni_type",
":method",
":params",
":proxy",
":proxy_convenience_aliases",
":proxy_definitions",
":proxy_definitions_array",
":proxy_definitions_string",
@@ -820,6 +823,7 @@ cc_library(
":object",
":proxy_convenience_aliases",
":ref_base",
":self",
"//:jni_dep",
"//metaprogramming:cartesian_product",
"//metaprogramming:combine",
@@ -853,6 +857,7 @@ cc_library(
":object",
":proxy",
":ref_base",
":self",
"//:jni_dep",
"//implementation/jni_helper:lifecycle",
],
@@ -968,9 +973,11 @@ cc_library(
hdrs = ["selector_static_info.h"],
deps = [
":array",
":id_type",
":name_constants",
":object",
":return",
":self",
":void",
"//implementation/jni_helper:jni_typename_to_string",
"//metaprogramming:name_constants",
@@ -1041,3 +1048,19 @@ cc_library(
name = "void",
hdrs = ["void.h"],
)

cc_library(
name = "self",
hdrs = ["self.h"],
deps = [":static"],
)

cc_test(
name = "self_test",
srcs = ["self_test.cc"],
deps = [
"//:jni_bind",
"//:jni_test",
"@googletest//:gtest_main",
],
)
1 change: 1 addition & 0 deletions implementation/array_test.cc
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "implementation/fake_test_constants.h"
6 changes: 3 additions & 3 deletions implementation/class.h
Original file line number Diff line number Diff line change
@@ -22,11 +22,11 @@
#include <tuple>
#include <type_traits>

#include "constructor.h"
#include "field.h"
#include "object.h"
#include "implementation/constructor.h"
#include "implementation/field.h"
#include "implementation/method.h"
#include "implementation/no_idx.h"
#include "implementation/object.h"
#include "implementation/static.h"
#include "jni_dep.h"
#include "metaprogramming/all_unique.h"
2 changes: 2 additions & 0 deletions implementation/id.h
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
#include "implementation/no_idx.h"
#include "implementation/proxy_convenience_aliases.h"
#include "implementation/selector_static_info.h"
#include "implementation/self.h"
#include "implementation/signature.h"
#include "metaprogramming/replace_string.h"

@@ -180,6 +181,7 @@ struct Id {
using CDecl = CDecl_t<VoidIfVoid_t<MaterializeT>>;

static constexpr std::size_t kRank = Rankifier::Rank(Val());
static constexpr bool kIsSelf = std::is_same_v<RawValT, Self>;

static constexpr const char* Name() {
if constexpr (kIdType == IdType::CLASS) {
13 changes: 10 additions & 3 deletions implementation/method_ref.h
Original file line number Diff line number Diff line change
@@ -19,10 +19,12 @@

#include <mutex>
#include <tuple>
#include <type_traits>
#include <utility>

#include "implementation/class_loader.h"
#include "implementation/class_ref.h"
#include "implementation/default_class_loader.h"
#include "implementation/id_type.h"
#include "implementation/jni_helper/invoke.h"
#include "implementation/jni_helper/invoke_static.h"
@@ -33,6 +35,7 @@
#include "implementation/method.h"
#include "implementation/params.h"
#include "implementation/proxy.h"
#include "implementation/proxy_convenience_aliases.h"
#include "implementation/proxy_definitions.h"
#include "implementation/proxy_definitions_array.h"
#include "implementation/proxy_definitions_string.h"
@@ -59,14 +62,18 @@ template <typename IdT_, IdType kReturnIDType>
struct OverloadRef {
using IdT = IdT_;
using ReturnIdT = typename IdT::template ChangeIdType<kReturnIDType>;
using ReturnProxied =
Return_t<typename ReturnIdT::MaterializeCDeclT, ReturnIdT>;
using SelfIdT = typename IdT::template ChangeIdType<IdType::CLASS>;

using ReturnProxied = std::conditional_t<
ReturnIdT::kIsSelf,
Return_t<typename SelfIdT::MaterializeCDeclT, SelfIdT>,
Return_t<typename ReturnIdT::MaterializeCDeclT, ReturnIdT> >;

static jmethodID GetMethodID(jclass clazz) {
static jni::metaprogramming::DoubleLockedValue<jmethodID> return_value;

return return_value.LoadAndMaybeInit([=]() {
if constexpr (IdT_::JniT::GetClassLoader() == kDefaultClassLoader) {
if constexpr (IdT::JniT::GetClassLoader() == kDefaultClassLoader) {
GetDefaultLoadedMethodList().push_back(&return_value);
}

3 changes: 2 additions & 1 deletion implementation/proxy.h
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
#include "implementation/object.h"
#include "implementation/proxy_convenience_aliases.h"
#include "implementation/ref_base.h"
#include "implementation/self.h"
#include "jni_dep.h"
#include "metaprogramming/cartesian_product.h"
#include "metaprogramming/combine.h"
@@ -51,7 +52,7 @@ struct Proxy;
// CDecls for all declarable types (these index into proxy definitions).
using AllKeys =
Corpus_t<JniUserDefinedCorpusTag, void, jboolean, jbyte, jshort, jint,
jfloat, jlong, jchar, jdouble, jstring, jobject, jarray,
jfloat, jlong, jchar, jdouble, jstring, jobject, Self, jarray,
jobjectArray, jintArray, jbooleanArray, jbyteArray, jcharArray,
jshortArray, jdoubleArray, jfloatArray, jlongArray>;

43 changes: 43 additions & 0 deletions implementation/proxy_definitions.h
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@
#include "implementation/object.h"
#include "implementation/proxy.h"
#include "implementation/ref_base.h"
#include "implementation/self.h"
#include "jni_dep.h"

namespace jni {
@@ -185,6 +186,48 @@ struct Proxy<JObject,
};
};

////////////////////////////////////////////////////////////////////////////////
// Self Proxy Definitions.
////////////////////////////////////////////////////////////////////////////////
template <typename SelfType>
struct Proxy<SelfType,
typename std::enable_if_t<std::is_same_v<SelfType, Self>>>
: public ProxyBase<jobject> {
using AsDecl = std::tuple<Self>;
using AsArg = std::tuple<Self>;

template <typename IdT>
using SelfIdT_t = typename IdT::template ChangeIdType<IdType::CLASS>;

template <typename Id>
struct Helper {
static constexpr auto kClass{Id::Val()};
static constexpr auto kClassLoader{Id::JniT::GetClassLoader()};

// TODO(b/174272629): Class loaders should also be enforced.
using type = LocalObject<kClass, kClassLoader, kDefaultJvm>;
};

template <typename Id>
using AsReturn = typename Helper<Id>::type;

template <typename IdT, typename T>
static constexpr bool kViable =
Proxy<jobject>::template kViable<SelfIdT_t<IdT>, T>;

// Applies for both local and global.
template <typename T>
static jobject ProxyAsArg(T& t) {
return jobject{t};
};

// Applies for both local and global.
template <typename T>
static jobject ProxyAsArg(T&& t) {
return t.Release();
};
};

} // namespace jni

#endif // JNI_BIND_TYPE_PROXY_DEFINITIONS_H_
25 changes: 22 additions & 3 deletions implementation/selector_static_info.h
Original file line number Diff line number Diff line change
@@ -20,17 +20,29 @@
#include <string_view>

#include "implementation/array.h"
#include "implementation/id_type.h"
#include "implementation/jni_helper/jni_typename_to_string.h"
#include "implementation/name_constants.h"
#include "implementation/object.h"
#include "implementation/return.h"
#include "implementation/self.h"
#include "implementation/void.h"
#include "metaprogramming/name_constants.h"
#include "metaprogramming/repeat_string.h"
#include "metaprogramming/string_concatenate.h"

namespace jni {

template <bool useParent, typename T>
struct ParentIfSelf {
using type = T;
};

template <typename T>
struct ParentIfSelf<true, T> {
using type = typename T::template ChangeIdType<IdType::CLASS>;
};

// Helper to generate full signature information for a "selected" value, and
// possibly some container information. Here, |Selector| is |MethodSelection|,
// |FieldSelection|, etc.
@@ -39,10 +51,13 @@ namespace jni {
// types can be used that represent a specific selection upon an object. This
// consolidates all signature info.
//
// |Selector| must express a type alias for RawVal (e.g. jint, Class{...}, etc.)
// and a type alias |RawValT| which is std::decay_t<RawVal>;
template <typename Selector>
// |Selector| a type alias |RawValT| (e.g. jint, Class{...}, etc...).
template <typename SelectorIn>
struct SelectorStaticInfo {
static constexpr inline bool kIsSelf =
std::is_same_v<Self, typename SelectorIn::RawValT>;
using Selector = typename ParentIfSelf<kIsSelf, SelectorIn>::type;

template <std::size_t I>
struct IthRawTypeMember {
template <typename T>
@@ -98,6 +113,10 @@ struct SelectorStaticInfo {
return metaprogramming::StringConcatenate_v<
metaprogramming::Constants::L, kTypeNameOrNothingIfNotAnObject,
metaprogramming::Constants::semi_colon>;
} else if constexpr (kIsSelf) {
return metaprogramming::StringConcatenate_v<
metaprogramming::Constants::L, kTypeNameOrNothingIfNotAnObject,
metaprogramming::Constants::semi_colon>;
} else if constexpr (kIsVoid) {
return JavaTypeToString<void>();
} else {
28 changes: 28 additions & 0 deletions implementation/self.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef JNI_BIND_IMPLEMENTATION_SELF_H_
#define JNI_BIND_IMPLEMENTATION_SELF_H_

namespace jni {

// Tag to indicate you are referring to the enclosing class.
// Useful for builder patterns where the decorated object returned is identical.
struct Self {};

} // namespace jni

#endif // JNI_BIND_IMPLEMENTATION_SELF_H_
Loading

0 comments on commit 7649b1a

Please sign in to comment.