• 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 class Transformer {
36 public:
Transformer(panda::ArenaAllocator * allocator)37     explicit Transformer(panda::ArenaAllocator *allocator)
38         : program_(nullptr),
39           tsModuleList_(allocator->Adapter())
40     {
41     }
42     NO_COPY_SEMANTIC(Transformer);
43     ~Transformer() = default;
44 
45     void Transform(Program *program);
46 
47 private:
48     void TransformFromTS();
49     ir::AstNode *VisitTSNodes(ir::AstNode *parent);
50     ir::UpdateNodes VisitTSNode(ir::AstNode *childNode);
51     ir::UpdateNodes VisitTsModuleDeclaration(ir::TSModuleDeclaration *childNode, bool isExport = false);
52     std::vector<ir::AstNode *> VisitExportNamedVariable(ir::Statement *decl);
53     ir::AstNode *VisitTsImportEqualsDeclaration(ir::TSImportEqualsDeclaration *node);
54     ir::VariableDeclaration *CreateVariableDeclarationWithIdentify(util::StringView name,
55                                                                    VariableParsingFlags flags,
56                                                                    ir::AstNode *node,
57                                                                    bool isExport,
58                                                                    ir::Expression *init = nullptr);
59     ir::CallExpression *CreateCallExpressionForTsModule(ir::TSModuleDeclaration *node,
60                                                         util::StringView paramName,
61                                                         bool isExport = false);
62     ir::Expression *CreateTsModuleParam(util::StringView paramName, bool isExport);
63     ir::ExpressionStatement *CreateTsModuleAssignment(util::StringView name);
64     ir::Expression *CreateMemberExpressionFromQualified(ir::Expression *node);
65     util::StringView GetNameFromModuleDeclaration(ir::TSModuleDeclaration *node) const;
66     util::StringView GetParamName(ir::TSModuleDeclaration *node, util::StringView name) const;
67     binder::Scope *FindExportVariableInTsModuleScope(util::StringView name) const;
68     binder::Variable *FindTSModuleVariable(const ir::Expression *node, binder::Scope *scope) const;
69     void AddExportLocalEntryItem(util::StringView name, const ir::Identifier *identifier);
70     bool IsInstantiatedTSModule(const ir::Expression *node) const;
71     void SetOriginalNode(ir::UpdateNodes res, ir::AstNode *originalNode) const;
72 
IsTsModule()73     bool IsTsModule() const
74     {
75         return (tsModuleList_.size() != 0);
76     }
77 
78     template <typename T, typename... Args>
AllocNode(Args &&...args)79     T *AllocNode(Args &&... args)
80     {
81         auto ret = program_->Allocator()->New<T>(std::forward<Args>(args)...);
82         if (ret == nullptr) {
83             throw Error(ErrorType::GENERIC, "Unsuccessful allocation during parsing");
84         }
85         return ret;
86     }
87 
Allocator()88     ArenaAllocator *Allocator() const
89     {
90         return program_->Allocator();
91     }
92 
Binder()93     binder::Binder *Binder() const
94     {
95         return program_->Binder();
96     }
97 
Scope()98     binder::Scope *Scope() const
99     {
100         return Binder()->GetScope();
101     }
102 
GetCurrentTSModuleName()103     util::StringView GetCurrentTSModuleName() const
104     {
105         return tsModuleList_.back().name;
106     }
107 
FindTSModuleNameByScope(binder::Scope * scope)108     util::StringView FindTSModuleNameByScope(binder::Scope *scope) const
109     {
110         for (auto it : tsModuleList_) {
111             if (it.scope == scope) {
112                 return it.name;
113             }
114         }
115         UNREACHABLE();
116     }
117 
Extension()118     ScriptExtension Extension() const
119     {
120         return program_->Extension();
121     }
122 
GetSourceTextModuleRecord()123     SourceTextModuleRecord *GetSourceTextModuleRecord()
124     {
125         return program_->ModuleRecord();
126     }
127 
128     Program *program_;
129     ArenaVector<TsModuleInfo> tsModuleList_;
130 };
131 
132 }  // namespace panda::es2panda::parser
133 
134 #endif
135