1 /**
2 * Copyright (c) 2025 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 "ani_signature_builder.h"
17 #include <cstddef>
18 #include <vector>
19 #include <algorithm>
20 #include <sstream>
21
22 namespace {
23
ConvertFullname(const std::string & fullname)24 std::string ConvertFullname(const std::string &fullname)
25 {
26 std::string result = fullname;
27 std::replace(result.begin(), result.end(), '.', '/');
28 return result;
29 }
30
JoinParts(std::initializer_list<std::string_view> parts)31 std::string JoinParts(std::initializer_list<std::string_view> parts)
32 {
33 std::ostringstream oss;
34 bool first = true;
35 for (auto part : parts) {
36 if (!first) {
37 oss << '.';
38 }
39 oss << part;
40 first = false;
41 }
42 return oss.str();
43 }
44
45 } // namespace
46
47 namespace arkts::ani_signature {
48
49 class Type::Impl {
50 public:
51 std::string descriptor;
52 };
53
Type(std::unique_ptr<Type::Impl> impl)54 Type::Type(std::unique_ptr<Type::Impl> impl) : impl_(std::move(impl)) {}
55
56 Type::~Type() = default;
57
58 // CC-OFFNXT(G.FUN.02-CPP) different coedcheck for .h and .cpp
Type(const Type & other)59 Type::Type(const Type &other) : impl_(other.impl_ ? std::make_unique<Type::Impl>(*other.impl_) : nullptr) {}
60
61 // CC-OFFNXT(G.FUN.02-CPP) different coedcheck for .h and .cpp
operator =(const Type & other)62 Type &Type::operator=(const Type &other)
63 {
64 if (this != &other) {
65 impl_ = other.impl_ ? std::make_unique<Type::Impl>(*other.impl_) : nullptr;
66 }
67 return *this;
68 }
69
Type(Type && other)70 Type::Type(Type &&other) : impl_(std::move(other.impl_)) {}
71
operator =(Type && other)72 Type &Type::operator=(Type &&other)
73 {
74 if (this != &other) {
75 impl_ = std::move(other.impl_);
76 }
77 return *this;
78 }
79
Descriptor() const80 std::string Type::Descriptor() const
81 {
82 return (impl_ != nullptr) ? impl_->descriptor : "";
83 }
84
CreateType(const std::string & desc)85 Type CreateType(const std::string &desc)
86 {
87 auto tImpl = std::make_unique<Type::Impl>();
88 tImpl->descriptor = desc;
89 Type t(std::move(tImpl));
90 return t;
91 }
92
93 class Module::Impl {
94 public:
95 std::string name;
96 std::string descriptor;
97 };
98
Module(std::unique_ptr<Module::Impl> impl)99 Module::Module(std::unique_ptr<Module::Impl> impl) : impl_(std::move(impl)) {}
100
101 Module::~Module() = default;
102
103 // CC-OFFNXT(G.FUN.02-CPP) different coedcheck for .h and .cpp
Module(const Module & other)104 Module::Module(const Module &other) : impl_(other.impl_ ? std::make_unique<Module::Impl>(*other.impl_) : nullptr) {}
105
106 // CC-OFFNXT(G.FUN.02-CPP) different coedcheck for .h and .cpp
operator =(const Module & other)107 Module &Module::operator=(const Module &other)
108 {
109 if (this != &other) {
110 impl_ = other.impl_ ? std::make_unique<Module::Impl>(*other.impl_) : nullptr;
111 }
112 return *this;
113 }
114
Module(Module && other)115 Module::Module(Module &&other) : impl_(std::move(other.impl_)) {}
116
operator =(Module && other)117 Module &Module::operator=(Module &&other)
118 {
119 if (this != &other) {
120 impl_ = std::move(other.impl_);
121 }
122 return *this;
123 }
124
Descriptor() const125 std::string Module::Descriptor() const
126 {
127 return (impl_ != nullptr) ? impl_->descriptor : "";
128 }
129
Name() const130 std::string Module::Name() const
131 {
132 return (impl_ != nullptr) ? impl_->name : "";
133 }
134
135 class Namespace::Impl {
136 public:
137 std::string name;
138 std::string descriptor;
139 };
140
Namespace(std::unique_ptr<Namespace::Impl> impl)141 Namespace::Namespace(std::unique_ptr<Namespace::Impl> impl) : impl_(std::move(impl)) {}
142
143 Namespace::~Namespace() = default;
144
145 // CC-OFFNXT(G.FUN.02-CPP) different coedcheck for .h and .cpp
Namespace(const Namespace & other)146 Namespace::Namespace(const Namespace &other)
147 : impl_(other.impl_ ? std::make_unique<Namespace::Impl>(*other.impl_) : nullptr)
148 {
149 }
150 // CC-OFFNXT(G.FUN.02-CPP) different coedcheck for .h and .cpp
operator =(const Namespace & other)151 Namespace &Namespace::operator=(const Namespace &other)
152 {
153 if (this != &other) {
154 impl_ = other.impl_ ? std::make_unique<Namespace::Impl>(*other.impl_) : nullptr;
155 }
156 return *this;
157 }
158
Namespace(Namespace && other)159 Namespace::Namespace(Namespace &&other) : impl_(std::move(other.impl_)) {}
160
operator =(Namespace && other)161 Namespace &Namespace::operator=(Namespace &&other)
162 {
163 if (this != &other) {
164 impl_ = std::move(other.impl_);
165 }
166 return *this;
167 }
168
Descriptor() const169 std::string Namespace::Descriptor() const
170 {
171 return (impl_ != nullptr) ? impl_->descriptor : "";
172 }
173
Name() const174 std::string Namespace::Name() const
175 {
176 return (impl_ != nullptr) ? impl_->name : "";
177 }
178
BuildUndefined()179 Type Builder::BuildUndefined()
180 {
181 return CreateType("Lstd/core/Object;");
182 }
183
BuildNull()184 Type Builder::BuildNull()
185 {
186 return CreateType("Lstd/core/Object;");
187 }
188
BuildBoolean()189 Type Builder::BuildBoolean()
190 {
191 return CreateType("Z");
192 }
193
BuildChar()194 Type Builder::BuildChar()
195 {
196 return CreateType("C");
197 }
198
BuildByte()199 Type Builder::BuildByte()
200 {
201 return CreateType("B");
202 }
203
BuildShort()204 Type Builder::BuildShort()
205 {
206 return CreateType("S");
207 }
208
BuildInt()209 Type Builder::BuildInt()
210 {
211 return CreateType("I");
212 }
213
BuildLong()214 Type Builder::BuildLong()
215 {
216 return CreateType("J");
217 }
218
BuildFloat()219 Type Builder::BuildFloat()
220 {
221 return CreateType("F");
222 }
223
BuildDouble()224 Type Builder::BuildDouble()
225 {
226 return CreateType("D");
227 }
228
BuildModule(std::string_view fullName)229 Module Builder::BuildModule(std::string_view fullName)
230 {
231 auto mImpl = std::make_unique<Module::Impl>();
232 mImpl->name = std::string(fullName);
233 mImpl->descriptor = "L" + ConvertFullname(std::string(fullName)) + ";";
234 Module m(std::move(mImpl));
235 return m;
236 }
237
BuildNamespace(std::initializer_list<std::string_view> fullName)238 Namespace Builder::BuildNamespace(std::initializer_list<std::string_view> fullName)
239 {
240 auto nsImpl = std::make_unique<Namespace::Impl>();
241 std::string origName = JoinParts(fullName);
242 nsImpl->name = origName;
243 nsImpl->descriptor = "L" + ConvertFullname(origName) + ";";
244 Namespace ns(std::move(nsImpl));
245 return ns;
246 }
247
BuildNamespace(std::string_view fullName)248 Namespace Builder::BuildNamespace(std::string_view fullName)
249 {
250 auto nsImpl = std::make_unique<Namespace::Impl>();
251 std::string origName = std::string(fullName);
252 nsImpl->name = origName;
253 nsImpl->descriptor = "L" + ConvertFullname(origName) + ";";
254 Namespace ns(std::move(nsImpl));
255 return ns;
256 }
257
BuildClass(std::initializer_list<std::string_view> fullName)258 Type Builder::BuildClass(std::initializer_list<std::string_view> fullName)
259 {
260 std::string origName = JoinParts(fullName);
261 return CreateType("L" + ConvertFullname(origName) + ";");
262 }
263
BuildClass(std::string_view fullName)264 Type Builder::BuildClass(std::string_view fullName)
265 {
266 std::string origName = std::string(fullName);
267 return CreateType("L" + ConvertFullname(origName) + ";");
268 }
269
BuildEnum(std::initializer_list<std::string_view> fullName)270 Type Builder::BuildEnum(std::initializer_list<std::string_view> fullName)
271 {
272 std::string origName = JoinParts(fullName);
273 return CreateType("L" + ConvertFullname(origName) + ";");
274 }
275
BuildEnum(std::string_view fullName)276 Type Builder::BuildEnum(std::string_view fullName)
277 {
278 std::string origName = std::string(fullName);
279 return CreateType("L" + ConvertFullname(origName) + ";");
280 }
281
BuildPartial(std::initializer_list<std::string_view> fullName)282 Type Builder::BuildPartial(std::initializer_list<std::string_view> fullName)
283 {
284 std::string origName = JoinParts(fullName);
285 return CreateType("L" + ConvertFullname(origName) + "$partial;");
286 }
287
BuildPartial(std::string_view fullName)288 Type Builder::BuildPartial(std::string_view fullName)
289 {
290 std::string origName = std::string(fullName);
291 return CreateType("L" + ConvertFullname(origName) + "$partial;");
292 }
293
BuildRequired(std::initializer_list<std::string_view> fullName)294 Type Builder::BuildRequired(std::initializer_list<std::string_view> fullName)
295 {
296 std::string origName = JoinParts(fullName);
297 return CreateType("L" + ConvertFullname(origName) + ";");
298 }
299
BuildRequired(std::string_view fullName)300 Type Builder::BuildRequired(std::string_view fullName)
301 {
302 std::string origName = std::string(fullName);
303 return CreateType("L" + ConvertFullname(origName) + ";");
304 }
305
BuildFunctionalObject(std::size_t nrRequiredArgs,bool hasResetArgs)306 Type Builder::BuildFunctionalObject(std::size_t nrRequiredArgs, bool hasResetArgs)
307 {
308 std::string descriptor;
309 const int reserveLength = 30U;
310 descriptor.reserve(reserveLength);
311
312 descriptor += "Lstd/core/Function";
313 if (hasResetArgs) {
314 descriptor += "R";
315 }
316 descriptor += std::to_string(nrRequiredArgs) + ";";
317
318 return CreateType(descriptor);
319 }
320
BuildArray(Type const & type)321 Type Builder::BuildArray(Type const &type)
322 {
323 return CreateType("[" + type.Descriptor());
324 }
325
BuildSignatureDescriptor(std::initializer_list<Type> args)326 std::string Builder::BuildSignatureDescriptor(std::initializer_list<Type> args)
327 {
328 std::string result;
329 for (const auto &arg : args) {
330 result += arg.Descriptor();
331 }
332 result += ":V";
333 return result;
334 }
335
BuildSignatureDescriptor(std::initializer_list<Type> args,Type const & ret)336 std::string Builder::BuildSignatureDescriptor(std::initializer_list<Type> args, Type const &ret)
337 {
338 std::string result;
339 for (const auto &arg : args) {
340 result += arg.Descriptor();
341 }
342 result += ":" + ret.Descriptor();
343 return result;
344 }
345
BuildConstructorName()346 std::string Builder::BuildConstructorName()
347 {
348 return "<ctor>";
349 }
350
BuildSetterName(std::string_view name)351 std::string Builder::BuildSetterName(std::string_view name)
352 {
353 return "<set>" + std::string(name);
354 }
355
BuildGetterName(std::string_view name)356 std::string Builder::BuildGetterName(std::string_view name)
357 {
358 return "<get>" + std::string(name);
359 }
360
361 // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
362 class SignatureBuilder::Impl {
363 public:
Impl()364 Impl() : ret_(Builder::BuildUndefined()) {}
365
AddParam(const Type & type)366 void AddParam(const Type &type)
367 {
368 params_.push_back(type);
369 }
370
SetReturn(const Type & type)371 void SetReturn(const Type &type)
372 {
373 ret_ = type;
374 retSet_ = true;
375 }
376
BuildSignature() const377 std::string BuildSignature() const
378 {
379 std::string result;
380 for (const auto ¶m : params_) {
381 result += param.Descriptor();
382 }
383 result += ":" + (retSet_ ? ret_.Descriptor() : "V");
384 return result;
385 }
386
387 private:
388 std::vector<Type> params_;
389 Type ret_;
390 bool retSet_ {false};
391 };
392 // NOLINTEND(misc-non-private-member-variables-in-classes)
393
SignatureBuilder()394 SignatureBuilder::SignatureBuilder() : impl_(std::make_unique<Impl>()) {}
395
396 SignatureBuilder::~SignatureBuilder() = default;
397
SignatureBuilder(SignatureBuilder && other)398 SignatureBuilder::SignatureBuilder(SignatureBuilder &&other) : impl_(std::move(other.impl_)) {}
399
operator =(SignatureBuilder && other)400 SignatureBuilder &SignatureBuilder::operator=(SignatureBuilder &&other)
401 {
402 if (this != &other) {
403 impl_ = std::move(other.impl_);
404 }
405 return *this;
406 }
407
AddUndefined()408 SignatureBuilder &SignatureBuilder::AddUndefined()
409 {
410 impl_->AddParam(Builder::BuildUndefined());
411 return *this;
412 }
413
AddNull()414 SignatureBuilder &SignatureBuilder::AddNull()
415 {
416 impl_->AddParam(Builder::BuildNull());
417 return *this;
418 }
419
AddBoolean()420 SignatureBuilder &SignatureBuilder::AddBoolean()
421 {
422 impl_->AddParam(Builder::BuildBoolean());
423 return *this;
424 }
425
AddChar()426 SignatureBuilder &SignatureBuilder::AddChar()
427 {
428 impl_->AddParam(Builder::BuildChar());
429 return *this;
430 }
431
AddByte()432 SignatureBuilder &SignatureBuilder::AddByte()
433 {
434 impl_->AddParam(Builder::BuildByte());
435 return *this;
436 }
437
AddShort()438 SignatureBuilder &SignatureBuilder::AddShort()
439 {
440 impl_->AddParam(Builder::BuildShort());
441 return *this;
442 }
443
AddInt()444 SignatureBuilder &SignatureBuilder::AddInt()
445 {
446 impl_->AddParam(Builder::BuildInt());
447 return *this;
448 }
449
AddLong()450 SignatureBuilder &SignatureBuilder::AddLong()
451 {
452 impl_->AddParam(Builder::BuildLong());
453 return *this;
454 }
455
AddFloat()456 SignatureBuilder &SignatureBuilder::AddFloat()
457 {
458 impl_->AddParam(Builder::BuildFloat());
459 return *this;
460 }
461
AddDouble()462 SignatureBuilder &SignatureBuilder::AddDouble()
463 {
464 impl_->AddParam(Builder::BuildDouble());
465 return *this;
466 }
467
Add(Type const & type)468 SignatureBuilder &SignatureBuilder::Add(Type const &type)
469 {
470 impl_->AddParam(type);
471 return *this;
472 }
473
AddClass(std::string_view fullName)474 SignatureBuilder &SignatureBuilder::AddClass(std::string_view fullName)
475 {
476 impl_->AddParam(Builder::BuildClass(fullName));
477 return *this;
478 }
479
AddClass(std::initializer_list<std::string_view> fullName)480 SignatureBuilder &SignatureBuilder::AddClass(std::initializer_list<std::string_view> fullName)
481 {
482 impl_->AddParam(Builder::BuildClass(fullName));
483 return *this;
484 }
485
AddEnum(std::string_view fullName)486 SignatureBuilder &SignatureBuilder::AddEnum(std::string_view fullName)
487 {
488 impl_->AddParam(Builder::BuildEnum(fullName));
489 return *this;
490 }
491
AddEnum(std::initializer_list<std::string_view> fullName)492 SignatureBuilder &SignatureBuilder::AddEnum(std::initializer_list<std::string_view> fullName)
493 {
494 impl_->AddParam(Builder::BuildEnum(fullName));
495 return *this;
496 }
497
AddPartial(std::string_view fullName)498 SignatureBuilder &SignatureBuilder::AddPartial(std::string_view fullName)
499 {
500 impl_->AddParam(Builder::BuildPartial(fullName));
501 return *this;
502 }
503
AddPartial(std::initializer_list<std::string_view> fullName)504 SignatureBuilder &SignatureBuilder::AddPartial(std::initializer_list<std::string_view> fullName)
505 {
506 impl_->AddParam(Builder::BuildPartial(fullName));
507 return *this;
508 }
509
AddRequired(std::string_view fullName)510 SignatureBuilder &SignatureBuilder::AddRequired(std::string_view fullName)
511 {
512 impl_->AddParam(Builder::BuildRequired(fullName));
513 return *this;
514 }
515
AddRequired(std::initializer_list<std::string_view> fullName)516 SignatureBuilder &SignatureBuilder::AddRequired(std::initializer_list<std::string_view> fullName)
517 {
518 impl_->AddParam(Builder::BuildRequired(fullName));
519 return *this;
520 }
521
AddFunctionalObject(std::size_t nrRequiredArgs,bool hasResetArgs)522 SignatureBuilder &SignatureBuilder::AddFunctionalObject(std::size_t nrRequiredArgs, bool hasResetArgs)
523 {
524 impl_->AddParam(Builder::BuildFunctionalObject(nrRequiredArgs, hasResetArgs));
525 return *this;
526 }
527
SetReturnUndefined()528 SignatureBuilder &SignatureBuilder::SetReturnUndefined()
529 {
530 impl_->SetReturn(Builder::BuildUndefined());
531 return *this;
532 }
533
SetReturnNull()534 SignatureBuilder &SignatureBuilder::SetReturnNull()
535 {
536 impl_->SetReturn(Builder::BuildNull());
537 return *this;
538 }
539
SetReturnBoolean()540 SignatureBuilder &SignatureBuilder::SetReturnBoolean()
541 {
542 impl_->SetReturn(Builder::BuildBoolean());
543 return *this;
544 }
545
SetReturnChar()546 SignatureBuilder &SignatureBuilder::SetReturnChar()
547 {
548 impl_->SetReturn(Builder::BuildChar());
549 return *this;
550 }
551
SetReturnByte()552 SignatureBuilder &SignatureBuilder::SetReturnByte()
553 {
554 impl_->SetReturn(Builder::BuildByte());
555 return *this;
556 }
557
SetReturnShort()558 SignatureBuilder &SignatureBuilder::SetReturnShort()
559 {
560 impl_->SetReturn(Builder::BuildShort());
561 return *this;
562 }
563
SetReturnInt()564 SignatureBuilder &SignatureBuilder::SetReturnInt()
565 {
566 impl_->SetReturn(Builder::BuildInt());
567 return *this;
568 }
569
SetReturnLong()570 SignatureBuilder &SignatureBuilder::SetReturnLong()
571 {
572 impl_->SetReturn(Builder::BuildLong());
573 return *this;
574 }
575
SetReturnFloat()576 SignatureBuilder &SignatureBuilder::SetReturnFloat()
577 {
578 impl_->SetReturn(Builder::BuildFloat());
579 return *this;
580 }
581
SetReturnDouble()582 SignatureBuilder &SignatureBuilder::SetReturnDouble()
583 {
584 impl_->SetReturn(Builder::BuildDouble());
585 return *this;
586 }
587
SetReturn(Type const & type)588 SignatureBuilder &SignatureBuilder::SetReturn(Type const &type)
589 {
590 impl_->SetReturn(type);
591 return *this;
592 }
593
SetReturnClass(std::string_view fullName)594 SignatureBuilder &SignatureBuilder::SetReturnClass(std::string_view fullName)
595 {
596 impl_->SetReturn(Builder::BuildClass(fullName));
597 return *this;
598 }
599
SetReturnClass(std::initializer_list<std::string_view> fullName)600 SignatureBuilder &SignatureBuilder::SetReturnClass(std::initializer_list<std::string_view> fullName)
601 {
602 impl_->SetReturn(Builder::BuildClass(fullName));
603 return *this;
604 }
605
SetReturnEnum(std::string_view fullName)606 SignatureBuilder &SignatureBuilder::SetReturnEnum(std::string_view fullName)
607 {
608 impl_->SetReturn(Builder::BuildEnum(fullName));
609 return *this;
610 }
611
SetReturnEnum(std::initializer_list<std::string_view> fullName)612 SignatureBuilder &SignatureBuilder::SetReturnEnum(std::initializer_list<std::string_view> fullName)
613 {
614 impl_->SetReturn(Builder::BuildEnum(fullName));
615 return *this;
616 }
617
SetReturnPartial(std::string_view fullName)618 SignatureBuilder &SignatureBuilder::SetReturnPartial(std::string_view fullName)
619 {
620 impl_->SetReturn(Builder::BuildPartial(fullName));
621 return *this;
622 }
623
SetReturnPartial(std::initializer_list<std::string_view> fullName)624 SignatureBuilder &SignatureBuilder::SetReturnPartial(std::initializer_list<std::string_view> fullName)
625 {
626 impl_->SetReturn(Builder::BuildPartial(fullName));
627 return *this;
628 }
629
SetReturnRequired(std::string_view fullName)630 SignatureBuilder &SignatureBuilder::SetReturnRequired(std::string_view fullName)
631 {
632 impl_->SetReturn(Builder::BuildRequired(fullName));
633 return *this;
634 }
635
SetReturnRequired(std::initializer_list<std::string_view> fullName)636 SignatureBuilder &SignatureBuilder::SetReturnRequired(std::initializer_list<std::string_view> fullName)
637 {
638 impl_->SetReturn(Builder::BuildRequired(fullName));
639 return *this;
640 }
641
SetReturnFunctionalObject(std::size_t nrRequiredArgs,bool hasResetArgs)642 SignatureBuilder &SignatureBuilder::SetReturnFunctionalObject(std::size_t nrRequiredArgs, bool hasResetArgs)
643 {
644 impl_->SetReturn(Builder::BuildFunctionalObject(nrRequiredArgs, hasResetArgs));
645 return *this;
646 }
647
BuildSignatureDescriptor()648 std::string SignatureBuilder::BuildSignatureDescriptor()
649 {
650 return impl_->BuildSignature();
651 }
652
653 } // namespace arkts::ani_signature
654