1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "bindings_implementation.h"
17
18namespace OHOS::Ace::Framework {
19
20template<typename T, template<typename> typename ImplDetail>
21thread_local std::string JSClassImpl<T, ImplDetail>::jsName;
22
23template<typename C, template<typename> typename ImplDetail>
24void JSClassImpl<C, ImplDetail>::Declare(const char* name)
25{
26    jsName = name;
27    ImplDetail<C>::Declare(name);
28}
29
30template<typename C, template<typename> typename ImplDetail>
31template<typename Base, typename R, typename... Args>
32void JSClassImpl<C, ImplDetail>::Method(const char* name, R (Base::*func)(Args...), MethodOptions options)
33{
34    static_assert(std::is_base_of_v<Base, C>, "Trying to bind an unrelated method!");
35    ImplDetail<C>::Method(name, new FunctionBinding(name, options, func));
36}
37
38template<typename C, template<typename> typename ImplDetail>
39template<typename R, typename... Args>
40void JSClassImpl<C, ImplDetail>::StaticMethod(const char* name, R (*func)(Args...), MethodOptions options)
41{
42    ImplDetail<C>::StaticMethod(name, new StaticFunctionBinding(name, options, func));
43}
44
45template<typename C, template<typename> typename ImplDetail>
46void JSClassImpl<C, ImplDetail>::StaticMethod(const char* name, JSFunctionCallback func)
47{
48    ImplDetail<C>::StaticMethod(name, new StaticFunctionBinding(name, MethodOptions::NONE, func));
49}
50
51template<typename C, template<typename> typename ImplDetail>
52template<typename T>
53void JSClassImpl<C, ImplDetail>::CustomMethod(const char* name, MemberFunctionCallback<T> callback)
54{
55    static_assert(std::is_base_of_v<T, C>, "Trying to bind an unrelated method!");
56    ImplDetail<C>::CustomMethod(name, new FunctionBinding(name, MethodOptions::NONE, callback));
57}
58
59template<typename C, template<typename> typename ImplDetail>
60void JSClassImpl<C, ImplDetail>::CustomMethod(const char* name, FunctionCallback callback)
61{
62    ImplDetail<C>::CustomMethod(name, callback);
63}
64
65template<typename C, template<typename> typename ImplDetail>
66template<typename T>
67void JSClassImpl<C, ImplDetail>::CustomMethod(const char* name, JSMemberFunctionCallback<T> callback)
68{
69    ImplDetail<C>::CustomMethod(name, new FunctionBinding(name, MethodOptions::NONE, callback));
70}
71
72template<typename C, template<typename> typename ImplDetail>
73template<typename T>
74void JSClassImpl<C, ImplDetail>::CustomProperty(
75    const char* name, MemberFunctionGetCallback<T> getter, MemberFunctionSetCallback<T> setter)
76{
77    static_assert(std::is_base_of_v<T, C>, "Trying to bind an unrelated method!");
78    ImplDetail<C>::CustomProperty(name, new FunctionBinding(name, MethodOptions::NONE, getter),
79        new FunctionBinding(name, MethodOptions::NONE, setter));
80}
81
82template<typename C, template<typename> typename ImplDetail>
83void JSClassImpl<C, ImplDetail>::CustomProperty(
84    const char* name, FunctionGetCallback getter, FunctionSetCallback setter)
85{
86    ImplDetail<C>::CustomProperty(name, getter, setter);
87}
88
89template<typename C, template<typename> typename ImplDetail>
90template<typename T>
91void JSClassImpl<C, ImplDetail>::CustomProperty(
92    const char* name, JSMemberFunctionCallback<T> getter, JSMemberFunctionCallback<T> setter)
93{
94    ImplDetail<C>::CustomProperty(name, new FunctionBinding(name, MethodOptions::NONE, getter),
95        new FunctionBinding(name, MethodOptions::NONE, setter));
96}
97
98template<typename C, template<typename> typename ImplDetail>
99void JSClassImpl<C, ImplDetail>::CustomStaticMethod(const char* name, FunctionCallback callback)
100{
101    ImplDetail<C>::CustomStaticMethod(name, callback);
102}
103
104template<typename C, template<typename> typename ImplDetail>
105void JSClassImpl<C, ImplDetail>::ExoticGetter(ExoticGetterCallback callback)
106{
107    ImplDetail<C>::ExoticGetter(callback);
108}
109
110template<typename C, template<typename> typename ImplDetail>
111void JSClassImpl<C, ImplDetail>::ExoticSetter(ExoticSetterCallback callback)
112{
113    ImplDetail<C>::ExoticSetter(callback);
114}
115
116template<typename C, template<typename> typename ImplDetail>
117void JSClassImpl<C, ImplDetail>::ExoticHasProperty(ExoticHasPropertyCallback callback)
118{
119    ImplDetail<C>::ExoticHasProperty(callback);
120}
121
122template<typename C, template<typename> typename ImplDetail>
123template<typename T>
124void JSClassImpl<C, ImplDetail>::StaticConstant(const char* name, T value)
125{
126    ImplDetail<C>::StaticConstant(name, value);
127}
128
129template<typename C, template<typename> typename ImplDetail>
130void JSClassImpl<C, ImplDetail>::Bind(BindingTarget bindTarget, FunctionCallback ctor)
131{
132    ImplDetail<C>::Bind(bindTarget, ctor);
133}
134
135template<typename C, template<typename> typename ImplDetail>
136void JSClassImpl<C, ImplDetail>::Bind(
137    BindingTarget bindTarget, JSFunctionCallback ctor, JSDestructorCallback<C> dtor, JSGCMarkCallback<C> gcMark)
138{
139    ImplDetail<C>::Bind(bindTarget, ctor, dtor, gcMark);
140}
141
142template<typename C, template<typename> typename ImplDetail>
143template<typename... Args>
144void JSClassImpl<C, ImplDetail>::Bind(
145    BindingTarget bindTarget, JSDestructorCallback<C> dtor, JSGCMarkCallback<C> gcMark)
146{
147    ImplDetail<C>::template Bind<Args...>(bindTarget, dtor, gcMark);
148}
149
150template<typename C, template<typename> typename ImplDetail>
151template<typename Base>
152void JSClassImpl<C, ImplDetail>::Inherit()
153{
154    static_assert(std::is_base_of_v<Base, C>, "Calling Inherit() on unrelated classes!");
155    ImplDetail<C>::template Inherit<Base>();
156}
157
158template<typename C, template<typename> typename ImplDetail>
159template<typename Base>
160void JSClassImpl<C, ImplDetail>::InheritAndBind(
161    BindingTarget bindTarget, JSFunctionCallback ctor, JSDestructorCallback<C> dtor, JSGCMarkCallback<C> gcMark)
162{
163    static_assert(std::is_base_of_v<Base, C>, "Calling Inherit() on unrelated classes!");
164    ImplDetail<C>::template InheritAndBind<Base>(bindTarget, ctor, dtor, gcMark);
165}
166
167template<typename C, template<typename> typename ImplDetail>
168const char* JSClassImpl<C, ImplDetail>::JSName()
169{
170    return jsName.c_str();
171}
172
173template<typename C, template<typename> typename ImplDetail>
174JSRef<JSObject> JSClassImpl<C, ImplDetail>::NewInstance()
175{
176    return JSRef<JSObject>::Make(ImplDetail<C>::NewInstance());
177}
178
179}; // namespace OHOS::Ace::Framework
180