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