1 /* 2 * Copyright (c) 2021-2024 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_RECORDTABLE_H 17 #define ES2PANDA_VARBINDER_RECORDTABLE_H 18 19 #include "macros.h" 20 #include "utils/arena_containers.h" 21 #include "util/ustring.h" 22 #include "util/enumbitops.h" 23 24 namespace ark::es2panda::parser { 25 class Program; 26 } // namespace ark::es2panda::parser 27 28 namespace ark::es2panda::checker { 29 class Signature; 30 } // namespace ark::es2panda::checker 31 32 namespace ark::es2panda::ir { 33 class ClassDefinition; 34 class TSInterfaceDeclaration; 35 class Identifier; 36 } // namespace ark::es2panda::ir 37 38 namespace ark::es2panda::varbinder { 39 class FunctionScope; 40 class BoundContext; 41 42 using ENUMBITOPS_OPERATORS; 43 44 enum class RecordTableFlags : uint32_t { 45 NONE = 0U, 46 EXTERNAL = 1U << 0U, 47 }; 48 49 } // namespace ark::es2panda::varbinder 50 51 template <> 52 struct enumbitops::IsAllowedType<ark::es2panda::varbinder::RecordTableFlags> : std::true_type { 53 }; 54 55 namespace ark::es2panda::varbinder { 56 57 class RecordTable { 58 public: 59 explicit RecordTable(ArenaAllocator *allocator, parser::Program *program, RecordTableFlags flags) 60 : classDefinitions_(allocator->Adapter()), 61 interfaceDeclarations_(allocator->Adapter()), 62 signatures_(allocator->Adapter()), 63 program_(program), 64 flags_(flags) 65 { 66 } 67 68 NO_COPY_SEMANTIC(RecordTable); 69 NO_MOVE_SEMANTIC(RecordTable); 70 71 ~RecordTable() = default; 72 73 bool IsExternal() const 74 { 75 return (flags_ & RecordTableFlags::EXTERNAL) != 0; 76 } 77 78 ArenaSet<ir::ClassDefinition *> &ClassDefinitions() 79 { 80 return classDefinitions_; 81 } 82 83 const ArenaSet<ir::ClassDefinition *> &ClassDefinitions() const 84 { 85 return classDefinitions_; 86 } 87 88 ArenaSet<ir::TSInterfaceDeclaration *> &InterfaceDeclarations() 89 { 90 return interfaceDeclarations_; 91 } 92 93 const ArenaSet<ir::TSInterfaceDeclaration *> &InterfaceDeclarations() const 94 { 95 return interfaceDeclarations_; 96 } 97 98 ArenaVector<FunctionScope *> &Signatures() 99 { 100 return signatures_; 101 } 102 103 const ArenaVector<FunctionScope *> &Signatures() const 104 { 105 return signatures_; 106 } 107 108 void SetClassDefinition(ir::ClassDefinition *classDefinition) 109 { 110 record_ = classDefinition; 111 } 112 113 ir::ClassDefinition *ClassDefinition() 114 { 115 return std::holds_alternative<ir::ClassDefinition *>(record_) ? std::get<ir::ClassDefinition *>(record_) 116 : nullptr; 117 } 118 119 const ir::ClassDefinition *ClassDefinition() const 120 { 121 return std::holds_alternative<ir::ClassDefinition *>(record_) ? std::get<ir::ClassDefinition *>(record_) 122 : nullptr; 123 } 124 125 void SetInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDeclaration) 126 { 127 record_ = interfaceDeclaration; 128 } 129 130 ir::TSInterfaceDeclaration *InterfaceDeclaration() 131 { 132 return std::holds_alternative<ir::TSInterfaceDeclaration *>(record_) 133 ? std::get<ir::TSInterfaceDeclaration *>(record_) 134 : nullptr; 135 } 136 137 const ir::TSInterfaceDeclaration *InterfaceDeclaration() const 138 { 139 return std::holds_alternative<ir::TSInterfaceDeclaration *>(record_) 140 ? std::get<ir::TSInterfaceDeclaration *>(record_) 141 : nullptr; 142 } 143 144 void SetProgram(parser::Program *program) 145 { 146 program_ = program; 147 } 148 149 parser::Program *Program() 150 { 151 return program_; 152 } 153 154 const parser::Program *Program() const 155 { 156 return program_; 157 } 158 159 util::StringView RecordName() const; 160 161 private: 162 friend class BoundContext; 163 using RecordHolder = std::variant<ir::ClassDefinition *, ir::TSInterfaceDeclaration *, std::nullptr_t>; 164 165 ArenaSet<ir::ClassDefinition *> classDefinitions_; 166 ArenaSet<ir::TSInterfaceDeclaration *> interfaceDeclarations_; 167 ArenaVector<varbinder::FunctionScope *> signatures_; 168 RecordHolder record_ {nullptr}; 169 parser::Program *program_ {}; 170 BoundContext *boundCtx_ {}; 171 RecordTableFlags flags_ {}; 172 }; 173 174 class BoundContext { 175 public: 176 explicit BoundContext(RecordTable *recordTable, ir::ClassDefinition *classDef, bool force = false); 177 explicit BoundContext(RecordTable *recordTable, ir::TSInterfaceDeclaration *interfaceDecl, bool force = false); 178 ~BoundContext(); 179 180 NO_COPY_SEMANTIC(BoundContext); 181 NO_MOVE_SEMANTIC(BoundContext); 182 183 void *operator new(size_t) = delete; 184 void *operator new[](size_t) = delete; 185 186 util::StringView FormRecordName() const; 187 188 private: 189 BoundContext *prev_; 190 RecordTable *recordTable_; 191 RecordTable::RecordHolder currentRecord_ {nullptr}; 192 RecordTable::RecordHolder savedRecord_ {nullptr}; 193 ir::Identifier *recordIdent_ {nullptr}; 194 }; 195 196 } // namespace ark::es2panda::varbinder 197 198 #endif // ES2PANDA_VARBINDER_RECORDTABLE_H 199