• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_PARSER_TRANSFORMER_TRANSFORMER_H
17 #define ES2PANDA_PARSER_TRANSFORMER_TRANSFORMER_H
18 
19 #include <macros.h>
20 
21 #include "binder/binder.h"
22 #include "binder/scope.h"
23 #include "ir/astNode.h"
24 #include "parser/module/sourceTextModuleRecord.h"
25 #include "parser/parserFlags.h"
26 #include "parser/program/program.h"
27 
28 namespace panda::es2panda::parser {
29 
30 struct TsModuleInfo {
31     util::StringView name;
32     binder::Scope *scope;
33 };
34 
35 struct TsEnumInfo {
36     util::StringView name;
37     binder::Scope *scope;
38 };
39 
40 using PrivatePropertyMap = std::unordered_map<util::StringView, util::StringView>;
41 using ComputedPropertyMap = std::unordered_map<ir::Statement *, util::StringView>;
42 
43 struct ClassInfo {
44     util::StringView name;
45     size_t propertyIndex;
46     PrivatePropertyMap *bindNameMap;
47     ComputedPropertyMap *computedPropertyMap;
48 };
49 
50 class DuringClass {
51 public:
DuringClass(ArenaVector<ClassInfo> * classList,util::StringView name)52     explicit DuringClass(ArenaVector<ClassInfo> *classList, util::StringView name)
53     {
54         classList_ = classList;
55         classList_->push_back({name, 0, &bindNameMap_, &computedPropertyMap_});
56     }
57 
~DuringClass()58     ~DuringClass()
59     {
60         classList_->pop_back();
61     }
62 
63 private:
64     PrivatePropertyMap bindNameMap_ {};
65     ComputedPropertyMap computedPropertyMap_ {};
66     ArenaVector<ClassInfo> *classList_ {nullptr};
67 };
68 
69 class Transformer {
70 public:
Transformer(panda::ArenaAllocator * allocator)71     explicit Transformer(panda::ArenaAllocator *allocator)
72         : program_(nullptr),
73           tsModuleList_(allocator->Adapter()),
74           tsEnumList_(allocator->Adapter()),
75           classList_(allocator->Adapter())
76     {
77     }
78     NO_COPY_SEMANTIC(Transformer);
79     ~Transformer() = default;
80 
81     void Transform(Program *program);
82     void CheckTransformedAstStructure(const Program *program) const;
83 
84 private:
85     static constexpr std::string_view PRIVATE_PROPERTY_SIGN = "#";
86     static constexpr std::string_view NEW_VAR_PREFIX = "##";
87     static constexpr std::string_view NEW_VAR_HEAD = "var_";
88     static constexpr std::string_view INDEX_DIVISION = "_";
89     static constexpr std::string_view CONSTRUCTOR_NAME = "undefined";
90     static constexpr std::string_view CLASS_PROTOTYPE = "prototype";
91     static constexpr std::string_view OBJECT_VAR_NAME = "Object";
92     static constexpr std::string_view FUNC_NAME_OF_DEFINE_PROPERTY = "defineProperty";
93     static constexpr std::string_view FUNC_NAME_OF_GET_OWN_PROPERTY_DESCRIPTOR = "getOwnPropertyDescriptor";
94 
95     void TransformFromTS();
96 
97     void AddVariableToNearestStatements(util::StringView name);
98     void PushVariablesToNearestStatements(ir::BlockStatement *ast);
99 
100     ir::AstNode *VisitTSNodes(ir::AstNode *parent);
101     ir::UpdateNodes VisitTSNode(ir::AstNode *childNode);
102     ir::UpdateNodes VisitTsModuleDeclaration(ir::TSModuleDeclaration *childNode, bool isExport = false);
103     std::vector<ir::AstNode *> VisitExportNamedVariable(ir::Statement *decl);
104     ir::AstNode *VisitTsImportEqualsDeclaration(ir::TSImportEqualsDeclaration *node);
105     ir::UpdateNodes VisitClassDeclaration(ir::ClassDeclaration *node);
106     ir::UpdateNodes VisitClassExpression(ir::ClassExpression *node);
107     void VisitTSParameterProperty(ir::ClassDefinition *node);
108     std::vector<ir::ExpressionStatement *> VisitInstanceProperty(ir::ClassDefinition *node);
109     std::vector<ir::ExpressionStatement *> VisitStaticProperty(ir::ClassDefinition *node,
110                                                                util::StringView name);
111     void VisitPrivateProperty(ir::ClassDefinition *node);
112     void VisitComputedProperty(ir::ClassDefinition *node);
113     size_t GetInsertPosForConstructor(ir::ClassDefinition *node);
114 
115     ir::VariableDeclaration *CreateVariableDeclarationWithIdentify(util::StringView name,
116                                                                    VariableParsingFlags flags,
117                                                                    ir::AstNode *node,
118                                                                    bool isExport,
119                                                                    ir::Expression *init = nullptr,
120                                                                    bool needBinding = true);
121     ir::CallExpression *CreateCallExpressionForTsModule(ir::TSModuleDeclaration *node,
122                                                         util::StringView name,
123                                                         bool isExport = false);
124     ir::Expression *CreateTsModuleParam(util::StringView paramName, bool isExport);
125     ir::ExpressionStatement *CreateTsModuleAssignment(util::StringView name);
126     ir::Expression *CreateMemberExpressionFromQualified(ir::Expression *node);
127     std::vector<ir::AstNode *> CreateClassDecorators(ir::ClassDeclaration *node,
128                                                      const std::vector<ir::AstNode *> &variableDeclarations);
129     std::vector<ir::AstNode *> CreateMethodDecorators(util::StringView className,
130                                                       ir::MethodDefinition *node,
131                                                       const std::vector<ir::AstNode *> &variableDeclarations,
132                                                       bool isStatic);
133     std::vector<ir::AstNode *> CreatePropertyDecorators(util::StringView className,
134                                                         ir::ClassProperty *node,
135                                                         const std::vector<ir::AstNode *> &variableDeclarations,
136                                                         bool isStatic);
137     ir::CallExpression *CreateGetOwnPropertyDescriptorCall(ir::Expression *target, ir::Expression *key);
138     ir::CallExpression *CreateDefinePropertyCall(ir::Expression *target, ir::Expression *key, ir::Expression *value);
139     std::vector<ir::AstNode *> CreateVariableDeclarationForDecorators(ir::AstNode *node);
140     std::vector<ir::AstNode *> CreateParamDecorators(util::StringView className,
141                                                      ir::MethodDefinition *node,
142                                                      const std::vector<ir::AstNode *> &variableDeclarations,
143                                                      bool isConstructor,
144                                                      bool isStatic);
145     ir::MemberExpression *CreateClassPrototype(util::StringView className);
146     ir::Expression *CreateDecoratorTarget(util::StringView className, bool isStatic);
147     ir::Identifier *CreateReferenceIdentifier(util::StringView name);
148     util::StringView CreatePrivatePropertyBindName(util::StringView name);
149     util::StringView CreateNewVariable(bool needAddToStatements = true);
150     util::StringView CreateNewVariableName() const;
151     util::StringView CreateUniqueName(const std::string &head, size_t *index = nullptr) const;
152 
153     util::StringView GetNameFromModuleDeclaration(ir::TSModuleDeclaration *node) const;
154     util::StringView GetParamName(ir::AstNode *node, util::StringView name) const;
155     ir::Expression *GetClassMemberName(ir::Expression *key, bool isComputed,
156                                        ir::Statement *node, bool inDecorator = true);
157     binder::Scope *FindExportVariableInTsModuleScope(util::StringView name) const;
158     binder::Variable *FindTSModuleVariable(const ir::Expression *node, const binder::Scope *scope, bool *isType) const;
159     util::StringView FindPrivatePropertyBindName(util::StringView name);
160     void AddExportLocalEntryItem(util::StringView name, const ir::Identifier *identifier);
161     void RemoveDefaultLocalExportEntry();
162     bool IsInstantiatedImportEquals(const ir::TSImportEqualsDeclaration *node, binder::Scope *scope) const;
163     void SetOriginalNode(ir::UpdateNodes res, ir::AstNode *originalNode) const;
164 
165     ir::UpdateNodes VisitTsEnumDeclaration(ir::TSEnumDeclaration *node, bool isExport = false);
166     ir::AstNode *CreateVariableDeclarationForTSEnumOrTSModule(util::StringView name, ir::AstNode *node, bool isExport);
167     util::StringView GetNameFromTsEnumDeclaration(const ir::TSEnumDeclaration *node) const;
168     ir::CallExpression *CreateCallExpressionForTsEnum(ir::TSEnumDeclaration *node, util::StringView name,
169                                                       bool isExport);
170     ir::ExpressionStatement *CreateTsEnumMember(ir::TSEnumMember *node, ir::TSEnumMember *preNode,
171                                                 util::StringView enumLiteralName);
172     ir::ExpressionStatement *CreateTsEnumMemberWithStringInit(ir::TSEnumMember *node,
173                                                               util::StringView enumLiteralName,
174                                                               util::StringView enumMemberName);
175     ir::ExpressionStatement *CreateTsEnumMemberWithNumberInit(ir::TSEnumMember *node,
176                                                               util::StringView enumLiteralName,
177                                                               util::StringView enumMemberName);
178     ir::ExpressionStatement *CreateTsEnumMemberWithoutInit(ir::TSEnumMember *node,
179                                                            ir::TSEnumMember *preNode,
180                                                            util::StringView enumLiteralName,
181                                                            util::StringView enumMemberName);
182     ArenaVector<ir::Expression *> CreateCallExpressionArguments(util::StringView name, bool isExport);
183     bool IsStringInitForEnumMember(const ir::Expression *expr, binder::Scope *scope) const;
184     bool IsStringForMemberExpression(const ir::MemberExpression *memberExpr, binder::Scope *scope) const;
185     bool IsInstantiatedNamespaceVariable(binder::Variable *var) const;
186     ArenaVector<binder::Variable *> FindFrontIdentifierTSVariables(const ir::Identifier *ident,
187                                                                    binder::Scope *scope) const;
188     void FindLocalTSVariables(binder::Scope *scope, const util::StringView name,
189                               const std::vector<binder::TSBindingType> &types,
190                               ArenaVector<binder::Variable *> &findRes) const;
191     void FindExportTSVariables(binder::Scope *scope, const util::StringView name,
192                                const std::vector<binder::TSBindingType> &types,
193                                ArenaVector<binder::Variable *> &findRes) const;
194     bool VerifyMemberExpressionDeque(binder::Variable *currVar, ArenaDeque<const ir::Expression *> members) const;
195     util::StringView GetNameForMemberExpressionItem(const ir::Expression *node) const;
196     util::StringView GetNameFromEnumMember(const ir::TSEnumMember *node) const;
197     binder::Scope *FindEnumMemberScope(const util::StringView name) const;
198     ir::MemberExpression *CreateMemberExpressionFromIdentifier(binder::Scope *scope, ir::Identifier *node);
199 
200     void CheckTransformedAstNodes(const ir::AstNode *parent, bool *passed) const;
201     void CheckTransformedAstNode(const ir::AstNode *parent, ir::AstNode *childNode, bool *passed) const;
202 
203     void ResetParentScopeForAstNodes(const ir::AstNode *parent) const;
204     void ResetParentScopeForAstNode(ir::AstNode *childNode) const;
205 
206     template <typename T>
207     ir::UpdateNodes VisitExportClassDeclaration(T *node);
208 
209     template <binder::TSBindingType type>
210     binder::Variable *FindTSVariable(const binder::Scope *scope, const util::StringView &name) const;
211 
212     bool IsValueReference(ir::Identifier *node);
213 
IsTsModule()214     bool IsTsModule() const
215     {
216         return (tsModuleList_.size() != 0);
217     }
218 
IsTsEnum()219     bool IsTsEnum() const
220     {
221         return (tsEnumList_.size() != 0);
222     }
223 
224     template <typename T, typename... Args>
AllocNode(Args &&...args)225     T *AllocNode(Args &&... args)
226     {
227         auto ret = program_->Allocator()->New<T>(std::forward<Args>(args)...);
228         if (ret == nullptr) {
229             throw Error(ErrorType::GENERIC, "Unsuccessful allocation during parsing");
230         }
231         return ret;
232     }
233 
Allocator()234     ArenaAllocator *Allocator() const
235     {
236         return program_->Allocator();
237     }
238 
Binder()239     binder::Binder *Binder() const
240     {
241         return program_->Binder();
242     }
243 
Scope()244     binder::Scope *Scope() const
245     {
246         return Binder()->GetScope();
247     }
248 
GetCurrentTSModuleName()249     util::StringView GetCurrentTSModuleName() const
250     {
251         return tsModuleList_.back().name;
252     }
253 
FindTSModuleNameByScope(binder::Scope * scope)254     util::StringView FindTSModuleNameByScope(binder::Scope *scope) const
255     {
256         for (auto it : tsModuleList_) {
257             if (it.scope == scope) {
258                 return it.name;
259             }
260         }
261         UNREACHABLE();
262     }
263 
FindTSEnumNameByScope(binder::Scope * scope)264     util::StringView FindTSEnumNameByScope(binder::Scope *scope) const
265     {
266         for (auto it : tsEnumList_) {
267             if (it.scope == scope) {
268                 return it.name;
269             }
270         }
271         UNREACHABLE();
272     }
273 
Extension()274     ScriptExtension Extension() const
275     {
276         return program_->Extension();
277     }
278 
GetSourceTextModuleRecord()279     SourceTextModuleRecord *GetSourceTextModuleRecord()
280     {
281         return program_->ModuleRecord();
282     }
283 
RecordName()284     util::StringView RecordName() const
285     {
286         return program_->RecordName();
287     }
288 
GetCurrentClassInfoPropertyIndex()289     size_t GetCurrentClassInfoPropertyIndex() const
290     {
291         return classList_.back().propertyIndex;
292     }
293 
SetCurrentClassInfoPropertyIndex(size_t newIndex)294     void SetCurrentClassInfoPropertyIndex(size_t newIndex)
295     {
296         classList_.back().propertyIndex = newIndex;
297     }
298 
AddPrivatePropertyBinding(util::StringView name,util::StringView bindName)299     void AddPrivatePropertyBinding(util::StringView name, util::StringView bindName)
300     {
301         classList_.back().bindNameMap->insert({name, bindName});
302     }
303 
AddComputedPropertyBinding(ir::Statement * property,util::StringView name)304     void AddComputedPropertyBinding(ir::Statement *property, util::StringView name)
305     {
306         classList_.back().computedPropertyMap->insert({property, name});
307     }
308 
GetComputedPropertyBinding(ir::Statement * property)309     util::StringView GetComputedPropertyBinding(ir::Statement *property)
310     {
311         auto classInfo = classList_.back();
312         auto res = classInfo.computedPropertyMap->find(property);
313         ASSERT(res != classInfo.computedPropertyMap->end());
314         return res->second;
315     }
316 
317     Program *program_;
318     ArenaVector<TsModuleInfo> tsModuleList_;
319     ArenaVector<TsEnumInfo> tsEnumList_;
320     ArenaVector<ClassInfo> classList_;
321     std::unordered_map<util::StringView, binder::Scope *> tempVarDeclStatements_ {};
322 };
323 
324 }  // namespace panda::es2panda::parser
325 
326 #endif
327