• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 - 2023 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_VARBINDER_ETSBINDER_H
17 #define ES2PANDA_VARBINDER_ETSBINDER_H
18 
19 #include "varbinder/TypedBinder.h"
20 #include "varbinder/recordTable.h"
21 #include "ir/ets/etsImportDeclaration.h"
22 #include "ir/ets/etsReExportDeclaration.h"
23 
24 namespace panda::es2panda::varbinder {
25 
26 using ComputedLambdaObjects = ArenaMap<const ir::AstNode *, std::pair<ir::ClassDefinition *, checker::Signature *>>;
27 
28 struct DynamicImportData {
29     const ir::ETSImportDeclaration *import;
30     const ir::AstNode *specifier;
31     Variable *variable;
32 };
33 
34 using DynamicImportVariables = ArenaUnorderedMap<const Variable *, DynamicImportData>;
35 
36 class ETSBinder : public TypedBinder {
37 public:
ETSBinder(ArenaAllocator * allocator)38     explicit ETSBinder(ArenaAllocator *allocator)
39         : TypedBinder(allocator),
40           globalRecordTable_(allocator, Program(), RecordTableFlags::NONE),
41           recordTable_(&globalRecordTable_),
42           externalRecordTable_(Allocator()->Adapter()),
43           defaultImports_(Allocator()->Adapter()),
44           dynamicImports_(Allocator()->Adapter()),
45           reExportImports_(Allocator()->Adapter()),
46           lambdaObjects_(Allocator()->Adapter()),
47           dynamicImportVars_(Allocator()->Adapter()),
48           importSpecifiers_(Allocator()->Adapter()),
49           resolvedImportPathesMap_(Allocator()->Adapter())
50     {
51         InitImplicitThisParam();
52     }
53 
54     NO_COPY_SEMANTIC(ETSBinder);
55     NO_MOVE_SEMANTIC(ETSBinder);
56     ~ETSBinder() = default;
57 
Extension()58     ScriptExtension Extension() const override
59     {
60         return ScriptExtension::ETS;
61     }
62 
BindingOptions()63     ResolveBindingOptions BindingOptions() const override
64     {
65         return ResolveBindingOptions::BINDINGS;
66     }
67 
GetRecordTable()68     RecordTable *GetRecordTable()
69     {
70         return recordTable_;
71     }
72 
GetRecordTable()73     const RecordTable *GetRecordTable() const
74     {
75         return recordTable_;
76     }
77 
GetGlobalRecordTable()78     RecordTable *GetGlobalRecordTable()
79     {
80         return &globalRecordTable_;
81     }
82 
GetGlobalRecordTable()83     const RecordTable *GetGlobalRecordTable() const
84     {
85         return &globalRecordTable_;
86     }
87 
GetExternalRecordTable()88     ArenaMap<parser::Program *, RecordTable *> &GetExternalRecordTable()
89     {
90         return externalRecordTable_;
91     }
92 
GetExternalRecordTable()93     const ArenaMap<parser::Program *, RecordTable *> &GetExternalRecordTable() const
94     {
95         return externalRecordTable_;
96     }
97 
LambdaObjects()98     const ComputedLambdaObjects &LambdaObjects() const
99     {
100         return lambdaObjects_;
101     }
102 
LambdaObjects()103     ComputedLambdaObjects &LambdaObjects()
104     {
105         return lambdaObjects_;
106     }
107 
108     void HandleCustomNodes(ir::AstNode *childNode) override;
109 
110     void IdentifierAnalysis() override;
111     void BuildClassDefinition(ir::ClassDefinition *classDef) override;
112     void BuildClassProperty(const ir::ClassProperty *prop) override;
113     void LookupIdentReference(ir::Identifier *ident) override;
114     bool BuildInternalName(ir::ScriptFunction *scriptFunc) override;
115     void AddCompilableFunction(ir::ScriptFunction *func) override;
116 
117     void LookupTypeReference(ir::Identifier *ident, bool allowDynamicNamespaces);
118     void LookupTypeArgumentReferences(ir::ETSTypeReference *typeRef);
119     void BuildInterfaceDeclaration(ir::TSInterfaceDeclaration *decl);
120     void BuildMemberExpression(ir::MemberExpression *memberExpr);
121     void BuildMethodDefinition(ir::MethodDefinition *methodDef);
122     void BuildImportDeclaration(ir::ETSImportDeclaration *decl);
123     void BuildETSNewClassInstanceExpression(ir::ETSNewClassInstanceExpression *classInstance);
124     void AddSpecifiersToTopBindings(ir::AstNode *specifier, const ir::ETSImportDeclaration *import);
125     ArenaVector<parser::Program *> GetExternalProgram(const util::StringView &sourceName,
126                                                       const ir::StringLiteral *importPath);
127     bool AddImportNamespaceSpecifiersToTopBindings(ir::AstNode *specifier,
128                                                    const varbinder::Scope::VariableMap &globalBindings,
129                                                    const parser::Program *importProgram,
130                                                    const varbinder::GlobalScope *importGlobalScope,
131                                                    const ir::ETSImportDeclaration *import);
132     bool AddImportSpecifiersToTopBindings(ir::AstNode *specifier, const varbinder::Scope::VariableMap &globalBindings,
133                                           const ir::ETSImportDeclaration *import,
134                                           const ArenaVector<parser::Program *> &recordRes,
135                                           std::vector<ir::ETSImportDeclaration *> viewedReExport);
136     Variable *FindImportSpecifiersVariable(const util::StringView &imported,
137                                            const varbinder::Scope::VariableMap &globalBindings,
138                                            const ArenaVector<parser::Program *> &recordRes);
139     Variable *FindStaticBinding(const ArenaVector<parser::Program *> &recordRes, const ir::StringLiteral *importPath);
140     void AddSpecifiersToTopBindings(
141         ir::AstNode *specifier, const ir::ETSImportDeclaration *import, ir::StringLiteral *path,
142         std::vector<ir::ETSImportDeclaration *> viewedReExport = std::vector<ir::ETSImportDeclaration *>());
143     void AddDynamicSpecifiersToTopBindings(ir::AstNode *specifier, const ir::ETSImportDeclaration *import);
144 
145     void ResolveInterfaceDeclaration(ir::TSInterfaceDeclaration *decl);
146     void ResolveMethodDefinition(ir::MethodDefinition *methodDef);
147     LocalScope *ResolvePropertyReference(ir::ClassProperty *prop, ClassScope *scope);
148     void ResolveEnumDeclaration(ir::TSEnumDeclaration *enumDecl);
149     void InitializeInterfaceIdent(ir::TSInterfaceDeclaration *decl);
150     void BuildExternalProgram(parser::Program *extProgram);
151     void BuildProgram();
152 
153     void BuildFunctionName(const ir::ScriptFunction *func) const;
154     void BuildFunctionType(ir::ETSFunctionType *funcType);
155     void BuildProxyMethod(ir::ScriptFunction *func, const util::StringView &containingClassName, bool isStatic);
156     void BuildLambdaObject(ir::AstNode *refNode, ir::ClassDefinition *lambdaObject, checker::Signature *signature);
157     void AddLambdaFunctionThisParam(ir::ScriptFunction *func);
158     void AddInvokeFunctionThisParam(ir::ScriptFunction *func);
159     void BuildLambdaObjectName(const ir::AstNode *refNode);
160     void FormLambdaName(util::UString &name, const util::StringView &signature);
161     void FormFunctionalInterfaceName(util::UString &name, const util::StringView &signature);
162     void BuildFunctionalInterfaceName(ir::ETSFunctionType *funcType);
163 
SetDefaultImports(ArenaVector<ir::ETSImportDeclaration * > defaultImports)164     void SetDefaultImports(ArenaVector<ir::ETSImportDeclaration *> defaultImports)
165     {
166         defaultImports_ = std::move(defaultImports);
167     }
168 
AddDynamicImport(ir::ETSImportDeclaration * import)169     void AddDynamicImport(ir::ETSImportDeclaration *import)
170     {
171         ASSERT(import->Language().IsDynamic());
172         dynamicImports_.push_back(import);
173     }
174 
DynamicImports()175     const ArenaVector<ir::ETSImportDeclaration *> &DynamicImports() const
176     {
177         return dynamicImports_;
178     }
179 
AddReExportImport(ir::ETSReExportDeclaration * reExport)180     void AddReExportImport(ir::ETSReExportDeclaration *reExport)
181     {
182         reExportImports_.push_back(reExport);
183     }
184 
ReExportImports()185     const ArenaVector<ir::ETSReExportDeclaration *> &ReExportImports() const
186     {
187         return reExportImports_;
188     }
189 
DynamicImportVars()190     const DynamicImportVariables &DynamicImportVars() const
191     {
192         return dynamicImportVars_;
193     }
194 
DefaultExport()195     const ir::AstNode *DefaultExport()
196     {
197         return defaultExport_;
198     }
199 
SetDefaultExport(ir::AstNode * defaultExport)200     void SetDefaultExport(ir::AstNode *defaultExport)
201     {
202         defaultExport_ = defaultExport;
203     }
204 
ResolvedImportPathesMap()205     const ArenaUnorderedMap<util::StringView, util::StringView> &ResolvedImportPathesMap() const
206     {
207         return resolvedImportPathesMap_;
208     }
209 
GetResolvedImportPath(const util::StringView & path)210     const util::StringView &GetResolvedImportPath(const util::StringView &path) const
211     {
212         ASSERT(resolvedImportPathesMap_.find(path) != resolvedImportPathesMap_.end());
213 
214         return resolvedImportPathesMap_.find(path)->second;
215     }
216 
FillResolvedImportPathes(const std::unordered_map<std::string,std::string> & map,ArenaAllocator * allocator)217     void FillResolvedImportPathes(const std::unordered_map<std::string, std::string> &map, ArenaAllocator *allocator)
218     {
219         for (const auto &path : map) {
220             resolvedImportPathesMap_.emplace(util::UString(path.first, allocator).View(),
221                                              util::UString(path.second, allocator).View());
222         }
223     }
224 
225     bool IsDynamicModuleVariable(const Variable *var) const;
226     bool IsDynamicNamespaceVariable(const Variable *var) const;
227     const DynamicImportData *DynamicImportDataForVar(const Variable *var) const;
228 
229     static constexpr std::string_view DEFAULT_IMPORT_SOURCE_FILE = "<default_import>.ets";
230     static constexpr std::string_view DEFAULT_IMPORT_SOURCE = R"(
231 import * from "std/core";
232 import * from "std/math";
233 import * from "std/containers";
234 import * from "std/time";
235 import * from "std/interop/js";
236 import * from "escompat";
237 )";
238 
239     void ResolveReferenceForScope(ir::AstNode *node, Scope *scope);
240     void ResolveReferencesForScope(ir::AstNode const *parent, Scope *scope);
241 
242 private:
243     void BuildClassDefinitionImpl(ir::ClassDefinition *classDef);
244     void InitImplicitThisParam();
245     void HandleStarImport(ir::TSQualifiedName *importName, util::StringView fullPath);
246     void ImportGlobalProperties(const ir::ClassDefinition *classDef);
247     bool ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable *var, const util::StringView &name,
248                                                       const ir::ClassElement *classElement);
249     void InsertForeignBinding(ir::AstNode *specifier, const ir::ETSImportDeclaration *import,
250                               const util::StringView &name, Variable *var);
251     void ImportAllForeignBindings(ir::AstNode *specifier, const varbinder::Scope::VariableMap &globalBindings,
252                                   const parser::Program *importProgram, const varbinder::GlobalScope *importGlobalScope,
253                                   const ir::ETSImportDeclaration *import);
254 
255     RecordTable globalRecordTable_;
256     RecordTable *recordTable_;
257     ArenaMap<parser::Program *, RecordTable *> externalRecordTable_;
258     ArenaVector<ir::ETSImportDeclaration *> defaultImports_;
259     ArenaVector<ir::ETSImportDeclaration *> dynamicImports_;
260     ArenaVector<ir::ETSReExportDeclaration *> reExportImports_;
261     ComputedLambdaObjects lambdaObjects_;
262     DynamicImportVariables dynamicImportVars_;
263     ir::Identifier *thisParam_ {};
264     ArenaVector<std::pair<util::StringView, util::StringView>> importSpecifiers_;
265     ArenaUnorderedMap<util::StringView, util::StringView> resolvedImportPathesMap_;
266     ir::AstNode *defaultExport_ {};
267 };
268 
269 }  // namespace panda::es2panda::varbinder
270 
271 #endif
272