1 /** 2 * Copyright (c) 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_IR_TYPED_H 17 #define ES2PANDA_IR_TYPED_H 18 19 #include "ir/astNode.h" 20 #include "ir/statement.h" 21 22 namespace ark::es2panda::checker { 23 // NOLINTBEGIN(readability-redundant-declaration) 24 bool IsTypeError(Type const *tp); 25 [[noreturn]] void ThrowEmptyError(); 26 // NOLINTEND(readability-redundant-declaration) 27 } // namespace ark::es2panda::checker 28 29 namespace ark::es2panda::ir { 30 31 template <typename T> 32 class Typed : public T { 33 public: 34 Typed() = delete; 35 ~Typed() override = default; 36 37 NO_COPY_OPERATOR(Typed); 38 NO_MOVE_SEMANTIC(Typed); 39 TsType() const40 [[nodiscard]] checker::Type const *TsType() const 41 { 42 if (UNLIKELY(IsTypeError(tsType_))) { 43 checker::ThrowEmptyError(); 44 } 45 return tsType_; 46 } 47 48 [[nodiscard]] checker::Type const *TsTypeOrError() const noexcept 49 { 50 return tsType_; 51 } 52 TsType()53 [[nodiscard]] checker::Type *TsType() 54 { 55 if (UNLIKELY(IsTypeError(tsType_))) { 56 checker::ThrowEmptyError(); 57 } 58 return tsType_; 59 } 60 61 [[nodiscard]] checker::Type *TsTypeOrError() noexcept 62 { 63 return tsType_; 64 } 65 66 void SetTsType(checker::Type *tsType) noexcept 67 { 68 tsType_ = tsType; 69 } 70 71 bool IsTyped() const override 72 { 73 return true; 74 } 75 76 protected: Typed(AstNodeType const type)77 explicit Typed(AstNodeType const type) : T(type) {} Typed(AstNodeType const type, ModifierFlags const flags)78 explicit Typed(AstNodeType const type, ModifierFlags const flags) : T(type, flags) {} 79 80 // NOTE: when cloning node its type is not copied but removed empty so that it can be re-checked further. Typed(Typed const &other)81 Typed(Typed const &other) : T(static_cast<T const &>(other)) {} 82 83 private: 84 checker::Type *tsType_ {}; 85 }; 86 87 class TypedAstNode : public Typed<AstNode> { 88 public: 89 TypedAstNode() = delete; 90 ~TypedAstNode() override = default; 91 92 NO_COPY_OPERATOR(TypedAstNode); 93 NO_MOVE_SEMANTIC(TypedAstNode); 94 95 protected: TypedAstNode(AstNodeType const type)96 explicit TypedAstNode(AstNodeType const type) : Typed<AstNode>(type) {} TypedAstNode(AstNodeType const type, ModifierFlags const flags)97 explicit TypedAstNode(AstNodeType const type, ModifierFlags const flags) : Typed<AstNode>(type, flags) {} 98 TypedAstNode(TypedAstNode const &other)99 TypedAstNode(TypedAstNode const &other) : Typed<AstNode>(static_cast<Typed<AstNode> const &>(other)) {} 100 }; 101 102 class AnnotatedAstNode : public Annotated<AstNode> { 103 public: 104 AnnotatedAstNode() = delete; 105 ~AnnotatedAstNode() override = default; 106 107 NO_COPY_OPERATOR(AnnotatedAstNode); 108 NO_MOVE_SEMANTIC(AnnotatedAstNode); 109 110 protected: AnnotatedAstNode(AstNodeType const type, TypeNode *const typeAnnotation)111 explicit AnnotatedAstNode(AstNodeType const type, TypeNode *const typeAnnotation) 112 : Annotated<AstNode>(type, typeAnnotation) 113 { 114 } AnnotatedAstNode(AstNodeType const type)115 explicit AnnotatedAstNode(AstNodeType const type) : Annotated<AstNode>(type) {} AnnotatedAstNode(AstNodeType const type, ModifierFlags const flags)116 explicit AnnotatedAstNode(AstNodeType const type, ModifierFlags const flags) : Annotated<AstNode>(type, flags) {} 117 AnnotatedAstNode(AnnotatedAstNode const &other)118 AnnotatedAstNode(AnnotatedAstNode const &other) : Annotated<AstNode>(static_cast<Annotated<AstNode> const &>(other)) 119 { 120 } 121 }; 122 123 class TypedStatement : public Typed<Statement> { 124 public: 125 TypedStatement() = delete; 126 ~TypedStatement() override = default; 127 128 NO_COPY_OPERATOR(TypedStatement); 129 NO_MOVE_SEMANTIC(TypedStatement); 130 131 protected: TypedStatement(AstNodeType type)132 explicit TypedStatement(AstNodeType type) : Typed<Statement>(type) {}; TypedStatement(AstNodeType type, ModifierFlags flags)133 explicit TypedStatement(AstNodeType type, ModifierFlags flags) : Typed<Statement>(type, flags) {}; 134 TypedStatement(TypedStatement const &other)135 TypedStatement(TypedStatement const &other) : Typed<Statement>(static_cast<Typed<Statement> const &>(other)) {} 136 137 inline static checker::Type *const CHECKED = reinterpret_cast<checker::Type *>(0x01); 138 }; 139 140 class AnnotatedStatement : public Annotated<Statement> { 141 public: 142 AnnotatedStatement() = delete; 143 ~AnnotatedStatement() override = default; 144 145 NO_COPY_OPERATOR(AnnotatedStatement); 146 NO_MOVE_SEMANTIC(AnnotatedStatement); 147 148 protected: AnnotatedStatement(AstNodeType type, TypeNode *typeAnnotation)149 explicit AnnotatedStatement(AstNodeType type, TypeNode *typeAnnotation) : Annotated<Statement>(type, typeAnnotation) 150 { 151 } 152 AnnotatedStatement(AstNodeType type)153 explicit AnnotatedStatement(AstNodeType type) : Annotated<Statement>(type) {} AnnotatedStatement(AstNodeType type, ModifierFlags flags)154 explicit AnnotatedStatement(AstNodeType type, ModifierFlags flags) : Annotated<Statement>(type, flags) {} 155 AnnotatedStatement(AnnotatedStatement const &other)156 AnnotatedStatement(AnnotatedStatement const &other) 157 : Annotated<Statement>(static_cast<Annotated<Statement> const &>(other)) 158 { 159 } 160 }; 161 162 } // namespace ark::es2panda::ir 163 164 #endif 165