• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-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 #ifndef ES2PANDA_UTIL_HELPERS_H
17 #define ES2PANDA_UTIL_HELPERS_H
18 
19 #include "varbinder/variableFlags.h"
20 #include "mem/pool_manager.h"
21 #include "util/ustring.h"
22 #include "ir/module/importSpecifier.h"
23 
24 #include <cmath>
25 #include <string>
26 
27 namespace ark::es2panda::parser {
28 class Program;
29 }  // namespace ark::es2panda::parser
30 
31 namespace ark::es2panda::varbinder {
32 class Variable;
33 }  // namespace ark::es2panda::varbinder
34 
35 namespace ark::es2panda::checker {
36 class ETSObjectType;
37 class Type;
38 }  // namespace ark::es2panda::checker
39 
40 namespace ark::es2panda::compiler {
41 class Literal;
42 }  // namespace ark::es2panda::compiler
43 
44 namespace ark::es2panda::ir {
45 class Expression;
46 class ScriptFunction;
47 class ClassDefinition;
48 class ClassProperty;
49 class Identifier;
50 class MethodDefinition;
51 class AstNode;
52 class ReturnStatement;
53 class CallExpression;
54 class ClassStaticBlock;
55 class TSInterfaceDeclaration;
56 class TSEnumDeclaration;
57 class ETSImportDeclaration;
58 enum class AstNodeType;
59 }  // namespace ark::es2panda::ir
60 
61 namespace ark::es2panda::util {
62 
63 class NodeAllocator {
64 public:
65     template <typename T, typename... Args>
NoSetParent(ArenaAllocator * alloc,Args &&...args)66     static T *NoSetParent(ArenaAllocator *alloc, Args &&...args)
67     {
68         return alloc->New<T>(std::forward<Args>(args)...);
69     }
70 
71     template <typename T, typename... Args>
ForceSetParent(ArenaAllocator * alloc,Args &&...args)72     static T *ForceSetParent(ArenaAllocator *alloc, Args &&...args)
73     {
74         auto *ret = NoSetParent<T>(alloc, std::forward<Args>(args)...);
75         if (ret == nullptr) {
76             return nullptr;
77         }
78         ret->Iterate([ret](ir::AstNode *child) { child->SetParent(ret); });
79         return ret;
80     }
81 
82     template <typename T, typename... Args>
Alloc(ArenaAllocator * alloc,Args &&...args)83     static T *Alloc(ArenaAllocator *alloc, Args &&...args)
84     {
85         auto *ret = NoSetParent<T>(alloc, std::forward<Args>(args)...);
86         if (ret == nullptr) {
87             return nullptr;
88         }
89         ret->Iterate([ret](ir::AstNode *child) {
90             ES2PANDA_ASSERT(child->Parent() == nullptr);
91             child->SetParent(ret);
92         });
93         return ret;
94     }
95 };
96 
97 class Helpers {
98 public:
99     Helpers() = delete;
100 
101     static bool IsGlobalIdentifier(const util::StringView &str);
102     static bool ContainSpreadElement(const ArenaVector<ir::Expression *> &args);
103     static util::StringView LiteralToPropName(const ir::Expression *lit);
104 
105     template <typename T>
106     static bool IsInteger(double number);
107     static bool IsIndex(double number);
108     static int64_t GetIndex(const util::StringView &str);
109 
110     static std::string ToString(double number);
111     static util::StringView ToStringView(ArenaAllocator *allocator, double number);
112     static util::StringView ToStringView(ArenaAllocator *allocator, int32_t number);
113     static util::StringView ToStringView(ArenaAllocator *allocator, uint32_t number);
114     static bool EndsWith(const std::string &str, const std::string &suffix);
115 
116     static const ir::ScriptFunction *GetContainingConstructor(const ir::AstNode *node);
117     static const ir::ScriptFunction *GetContainingConstructor(const ir::ClassProperty *node);
118 
119     template <typename T,
120               typename U = std::enable_if_t<
121                   std::is_convertible_v<std::remove_const_t<std::remove_pointer_t<T>> *, ir::AstNode *>,
122                   std::conditional_t<std::is_const_v<std::remove_pointer_t<T>>, const ir::AstNode *, ir::AstNode *>>>
FindAncestorGivenByType(T node,ir::AstNodeType type)123     static U FindAncestorGivenByType(T node, ir::AstNodeType type)
124     {
125         U iter = node->Parent();
126 
127         while (iter->Type() != type) {
128             if (iter->Parent() != nullptr) {
129                 iter = iter->Parent();
130                 continue;
131             }
132 
133             return nullptr;
134         }
135 
136         return iter;
137     }
138 
139     static const checker::ETSObjectType *GetContainingObjectType(const ir::AstNode *node);
140     static const ir::TSEnumDeclaration *GetContainingEnumDeclaration(const ir::AstNode *node);
141     static const ir::ClassDefinition *GetContainingClassDefinition(const ir::AstNode *node);
142     static const ir::TSInterfaceDeclaration *GetContainingInterfaceDeclaration(const ir::AstNode *node);
143     static const ir::MethodDefinition *GetContainingClassMethodDefinition(const ir::AstNode *node);
144     static const ir::ClassStaticBlock *GetContainingClassStaticBlock(const ir::AstNode *node);
145     static const ir::ScriptFunction *GetContainingFunction(const ir::AstNode *node);
146     static const ir::ClassDefinition *GetClassDefiniton(const ir::ScriptFunction *node);
147     static bool IsSpecialPropertyKey(const ir::Expression *expr);
148     static bool IsConstantPropertyKey(const ir::Expression *expr, bool isComputed);
149     static compiler::Literal ToConstantLiteral(const ir::Expression *expr);
150     static bool IsBindingPattern(const ir::AstNode *node);
151     static bool IsPattern(const ir::AstNode *node);
152     static std::vector<ir::Identifier *> CollectBindingNames(varbinder::VarBinder *vb, ir::Expression *node);
153     static util::StringView FunctionName(ArenaAllocator *allocator, const ir::ScriptFunction *func);
154     static void CheckImportedName(const ArenaVector<ir::ImportSpecifier *> &specifiers,
155                                   const ir::ImportSpecifier *specifier, const std::string &fileName);
156     static void CheckDefaultImportedName(const ArenaVector<ir::ImportDefaultSpecifier *> &specifiers,
157                                          const ir::ImportDefaultSpecifier *specifier, const std::string &fileName);
158     static void CheckDefaultImport(const ArenaVector<ir::ETSImportDeclaration *> &statements);
159     static std::tuple<util::StringView, bool> ParamName(ArenaAllocator *allocator, const ir::Expression *param,
160                                                         std::uint32_t index);
161     static bool IsAsyncMethod(ir::AstNode const *node);
162 
163     static bool IsGlobalVar(const ark::es2panda::varbinder::Variable *var);
164 
165     template <typename T, typename V>
ConvertVector(const ArenaVector<V * > & src)166     static ArenaVector<T *> ConvertVector(const ArenaVector<V *> &src)
167     {
168         ArenaVector<T *> dst(src.begin(), src.end(), src.get_allocator());
169         return dst;
170     }
171 
172     template <typename Source, typename Target>
IsTargetFitInSourceRange(Target target)173     static bool IsTargetFitInSourceRange(Target target)
174     {
175         if (!std::isfinite(target)) {
176             return true;
177         }
178 
179         // NOLINTNEXTLINE(misc-redundant-expression)
180         return target >= std::numeric_limits<Source>::lowest() &&
181                target <= static_cast<Target>(std::numeric_limits<Source>::max());
182     }
183 
184     static const uint32_t INVALID_INDEX = 4294967295L;
185 
186     static std::string CreateEscapedString(const std::string &str);
187     static std::string UTF16toUTF8(const char16_t c);
188 
189     template <typename... Elements>
190     static std::string AppendAll(Elements &&...elems);
191 
192     static std::pair<std::string_view, std::string_view> SplitSignature(std::string_view signature);
193 
194     static std::vector<std::string> const &StdLib();
195     static bool IsStdLib(const parser::Program *program);
196     [[nodiscard]] static checker::Type *CheckReturnTypeOfCheck([[maybe_unused]] const ir::AstNode *const node,
197                                                                checker::Type *const type);
198 
199     [[nodiscard]] static util::UString EscapeHTMLString(ArenaAllocator *allocator, const std::string &str);
200     [[nodiscard]] static ir::AstNode *DerefETSTypeReference(ir::AstNode *node);
201 };
202 
203 template <typename T>
IsInteger(double number)204 bool Helpers::IsInteger(double number)
205 {
206     if (std::fabs(number) <= static_cast<double>(std::numeric_limits<T>::max())) {
207         T intNum = static_cast<T>(number);
208 
209         if (static_cast<double>(intNum) == number) {
210             return true;
211         }
212     }
213 
214     return false;
215 }
216 
217 template <typename... Elements>
AppendAll(Elements &&...elems)218 std::string Helpers::AppendAll(Elements &&...elems)
219 {
220     std::string ret {};
221     ((ret += std::forward<Elements>(elems)), ...);
222     return ret;
223 }
224 
225 }  // namespace ark::es2panda::util
226 
227 #endif
228