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