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 AnnotationDeclaration; 36 class Identifier; 37 } // namespace ark::es2panda::ir 38 39 namespace ark::es2panda::varbinder { 40 class FunctionScope; 41 class BoundContext; 42 43 using ENUMBITOPS_OPERATORS; 44 45 enum class RecordTableFlags : uint32_t { 46 NONE = 0U, 47 EXTERNAL = 1U << 0U, 48 }; 49 50 } // namespace ark::es2panda::varbinder 51 52 template <> 53 struct enumbitops::IsAllowedType<ark::es2panda::varbinder::RecordTableFlags> : std::true_type { 54 }; 55 56 namespace ark::es2panda::varbinder { 57 58 class RecordTable { 59 public: 60 explicit RecordTable(ArenaAllocator *allocator, parser::Program *program, RecordTableFlags flags) 61 : classDefinitions_(allocator->Adapter()), 62 interfaceDeclarations_(allocator->Adapter()), 63 annotationDeclarations_(allocator->Adapter()), 64 signatures_(allocator->Adapter()), 65 program_(program), 66 flags_(flags) 67 { 68 } 69 70 NO_COPY_SEMANTIC(RecordTable); 71 NO_MOVE_SEMANTIC(RecordTable); 72 73 ~RecordTable() = default; 74 75 bool IsExternal() const 76 { 77 return (flags_ & RecordTableFlags::EXTERNAL) != 0; 78 } 79 80 ArenaSet<ir::ClassDefinition *> &ClassDefinitions() 81 { 82 return classDefinitions_; 83 } 84 85 const ArenaSet<ir::ClassDefinition *> &ClassDefinitions() const 86 { 87 return classDefinitions_; 88 } 89 90 ArenaSet<ir::TSInterfaceDeclaration *> &InterfaceDeclarations() 91 { 92 return interfaceDeclarations_; 93 } 94 95 const ArenaSet<ir::TSInterfaceDeclaration *> &InterfaceDeclarations() const 96 { 97 return interfaceDeclarations_; 98 } 99 100 ArenaSet<ir::AnnotationDeclaration *> &AnnotationDeclarations() 101 { 102 return annotationDeclarations_; 103 } 104 105 const ArenaSet<ir::AnnotationDeclaration *> &AnnotationDeclarations() const 106 { 107 return annotationDeclarations_; 108 } 109 110 ArenaVector<FunctionScope *> &Signatures() 111 { 112 return signatures_; 113 } 114 115 const ArenaVector<FunctionScope *> &Signatures() const 116 { 117 return signatures_; 118 } 119 120 void SetClassDefinition(ir::ClassDefinition *classDefinition) 121 { 122 record_ = classDefinition; 123 } 124 125 ir::ClassDefinition *ClassDefinition() 126 { 127 return std::holds_alternative<ir::ClassDefinition *>(record_) ? std::get<ir::ClassDefinition *>(record_) 128 : nullptr; 129 } 130 131 const ir::ClassDefinition *ClassDefinition() const 132 { 133 return std::holds_alternative<ir::ClassDefinition *>(record_) ? std::get<ir::ClassDefinition *>(record_) 134 : nullptr; 135 } 136 137 void SetInterfaceDeclaration(ir::TSInterfaceDeclaration *interfaceDeclaration) 138 { 139 record_ = interfaceDeclaration; 140 } 141 142 ir::TSInterfaceDeclaration *InterfaceDeclaration() 143 { 144 return std::holds_alternative<ir::TSInterfaceDeclaration *>(record_) 145 ? std::get<ir::TSInterfaceDeclaration *>(record_) 146 : nullptr; 147 } 148 149 const ir::TSInterfaceDeclaration *InterfaceDeclaration() const 150 { 151 return std::holds_alternative<ir::TSInterfaceDeclaration *>(record_) 152 ? std::get<ir::TSInterfaceDeclaration *>(record_) 153 : nullptr; 154 } 155 156 void SetAnnotationDeclaration(ir::AnnotationDeclaration *annotationDeclaration) 157 { 158 record_ = annotationDeclaration; 159 } 160 161 ir::AnnotationDeclaration *AnnotationDeclaration() 162 { 163 return std::holds_alternative<ir::AnnotationDeclaration *>(record_) 164 ? std::get<ir::AnnotationDeclaration *>(record_) 165 : nullptr; 166 } 167 168 const ir::AnnotationDeclaration *AnnotationDeclaration() const 169 { 170 return std::holds_alternative<ir::AnnotationDeclaration *>(record_) 171 ? std::get<ir::AnnotationDeclaration *>(record_) 172 : nullptr; 173 } 174 175 void SetProgram(parser::Program *program) 176 { 177 program_ = program; 178 } 179 180 parser::Program *Program() 181 { 182 return program_; 183 } 184 185 const parser::Program *Program() const 186 { 187 return program_; 188 } 189 190 util::StringView RecordName() const; 191 192 private: 193 friend class BoundContext; 194 using RecordHolder = 195 std::variant<ir::ClassDefinition *, ir::TSInterfaceDeclaration *, ir::AnnotationDeclaration *, std::nullptr_t>; 196 197 ArenaSet<ir::ClassDefinition *> classDefinitions_; 198 ArenaSet<ir::TSInterfaceDeclaration *> interfaceDeclarations_; 199 ArenaSet<ir::AnnotationDeclaration *> annotationDeclarations_; 200 ArenaVector<varbinder::FunctionScope *> signatures_; 201 RecordHolder record_ {nullptr}; 202 parser::Program *program_ {}; 203 BoundContext *boundCtx_ {}; 204 RecordTableFlags flags_ {}; 205 }; 206 207 class BoundContext { 208 public: 209 explicit BoundContext(RecordTable *recordTable, ir::ClassDefinition *classDef, bool force = false); 210 explicit BoundContext(RecordTable *recordTable, ir::TSInterfaceDeclaration *interfaceDecl, bool force = false); 211 explicit BoundContext(RecordTable *recordTable, ir::AnnotationDeclaration *annotationDecl, bool force = false); 212 ~BoundContext(); 213 214 NO_COPY_SEMANTIC(BoundContext); 215 NO_MOVE_SEMANTIC(BoundContext); 216 217 void *operator new(size_t) = delete; 218 void *operator new[](size_t) = delete; 219 220 util::StringView FormRecordName() const; 221 222 private: 223 BoundContext *prev_; 224 RecordTable *recordTable_; 225 RecordTable::RecordHolder currentRecord_ {nullptr}; 226 RecordTable::RecordHolder savedRecord_ {nullptr}; 227 ir::Identifier *recordIdent_ {nullptr}; 228 }; 229 230 } // namespace ark::es2panda::varbinder 231 232 #endif // ES2PANDA_VARBINDER_RECORDTABLE_H 233