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 PARSER_STATUS_CONTEXT_H 17 #define PARSER_STATUS_CONTEXT_H 18 19 #include "parserImpl.h" 20 21 namespace ark::es2panda::parser { 22 23 template <ParserStatus STATUS> 24 class SavedStatusContext { 25 public: SavedStatusContext(ParserContext *ctx)26 explicit SavedStatusContext(ParserContext *ctx) 27 // NOLINTNEXTLINE(readability-magic-numbers) 28 : ctx_(ctx), savedStatus_(static_cast<ParserStatus>(ctx->Status() & STATUS)) 29 { 30 // NOLINTNEXTLINE(readability-magic-numbers) 31 ctx->Status() |= STATUS; 32 } 33 34 NO_COPY_SEMANTIC(SavedStatusContext); 35 NO_MOVE_SEMANTIC(SavedStatusContext); 36 ~SavedStatusContext()37 ~SavedStatusContext() 38 { 39 if (savedStatus_ == ParserStatus::NO_OPTS) { 40 ctx_->Status() &= ~savedStatus_; 41 } 42 } 43 44 private: 45 ParserContext *ctx_; 46 ParserStatus savedStatus_; 47 }; 48 49 class SwitchContext : public SavedStatusContext<ParserStatus::IN_SWITCH> { 50 public: SwitchContext(ParserContext *ctx)51 explicit SwitchContext(ParserContext *ctx) : SavedStatusContext(ctx) {} 52 NO_COPY_SEMANTIC(SwitchContext); 53 NO_MOVE_SEMANTIC(SwitchContext); 54 ~SwitchContext() = default; 55 }; 56 57 class IterationContext : public SavedStatusContext<ParserStatus::IN_ITERATION> { 58 public: IterationContext(ParserContext *ctx)59 explicit IterationContext(ParserContext *ctx) : SavedStatusContext(ctx) {} 60 61 NO_COPY_SEMANTIC(IterationContext); 62 NO_MOVE_SEMANTIC(IterationContext); 63 ~IterationContext() = default; 64 }; 65 66 class FunctionParameterContext : public SavedStatusContext<ParserStatus::FUNCTION_PARAM> { 67 public: FunctionParameterContext(ParserContext *ctx)68 explicit FunctionParameterContext(ParserContext *ctx) : SavedStatusContext(ctx) {} 69 70 NO_COPY_SEMANTIC(FunctionParameterContext); 71 NO_MOVE_SEMANTIC(FunctionParameterContext); 72 ~FunctionParameterContext() = default; 73 }; 74 75 class SavedParserContext { 76 public: 77 template <typename... Args> SavedParserContext(ParserImpl *parser, Args &&...args)78 explicit SavedParserContext(ParserImpl *parser, Args &&...args) : parser_(parser), prev_(parser->context_) 79 { 80 parser_->context_ = ParserContext(&prev_, std::forward<Args>(args)...); 81 } 82 83 NO_COPY_SEMANTIC(SavedParserContext); 84 DEFAULT_MOVE_SEMANTIC(SavedParserContext); 85 ~SavedParserContext()86 ~SavedParserContext() 87 { 88 parser_->context_ = prev_; 89 } 90 91 private: 92 ParserImpl *parser_; 93 ParserContext prev_; 94 }; 95 96 class SavedClassPrivateContext { 97 public: SavedClassPrivateContext(ParserImpl *parser)98 explicit SavedClassPrivateContext(ParserImpl *parser) : parser_(parser), prev_(parser->classPrivateContext_) 99 { 100 parser_->classPrivateContext_ = ClassPrivateContext(&prev_); 101 } 102 103 NO_COPY_SEMANTIC(SavedClassPrivateContext); 104 DEFAULT_MOVE_SEMANTIC(SavedClassPrivateContext); 105 ~SavedClassPrivateContext()106 ~SavedClassPrivateContext() 107 { 108 parser_->classPrivateContext_ = prev_; 109 } 110 111 private: 112 ParserImpl *parser_; 113 ClassPrivateContext prev_; 114 }; 115 116 class FunctionContext : public SavedParserContext { 117 public: FunctionContext(ParserImpl *parser, ParserStatus newStatus)118 explicit FunctionContext(ParserImpl *parser, ParserStatus newStatus) : SavedParserContext(parser, newStatus) 119 { 120 if ((newStatus & ParserStatus::GENERATOR_FUNCTION) != 0) { 121 flags_ |= ir::ScriptFunctionFlags::GENERATOR; 122 } 123 124 if ((newStatus & ParserStatus::ASYNC_FUNCTION) != 0) { 125 flags_ |= ir::ScriptFunctionFlags::ASYNC; 126 } 127 128 if ((newStatus & ParserStatus::CONSTRUCTOR_FUNCTION) != 0) { 129 flags_ |= ir::ScriptFunctionFlags::CONSTRUCTOR; 130 } 131 } 132 Flags() const133 ir::ScriptFunctionFlags Flags() const 134 { 135 return flags_; 136 } 137 IsAsync() const138 bool IsAsync() const 139 { 140 return (flags_ & ir::ScriptFunctionFlags::ASYNC) != 0; 141 } 142 AddFlag(ir::ScriptFunctionFlags flags)143 void AddFlag(ir::ScriptFunctionFlags flags) 144 { 145 flags_ |= flags; 146 } 147 148 NO_COPY_SEMANTIC(FunctionContext); 149 NO_MOVE_SEMANTIC(FunctionContext); 150 ~FunctionContext() = default; 151 152 private: 153 ir::ScriptFunctionFlags flags_ {ir::ScriptFunctionFlags::NONE}; 154 }; 155 156 class ArrowFunctionContext : public FunctionContext { 157 public: ArrowFunctionContext(ParserImpl *parser, bool isAsync)158 explicit ArrowFunctionContext(ParserImpl *parser, bool isAsync) 159 : FunctionContext(parser, InitialFlags(parser->context_.Status())) 160 { 161 if (isAsync) { 162 AddFlag(ir::ScriptFunctionFlags::ASYNC); 163 } 164 165 AddFlag(ir::ScriptFunctionFlags::ARROW); 166 } 167 168 NO_COPY_SEMANTIC(ArrowFunctionContext); 169 NO_MOVE_SEMANTIC(ArrowFunctionContext); 170 ~ArrowFunctionContext() = default; 171 172 private: InitialFlags(ParserStatus currentStatus)173 static ParserStatus InitialFlags(ParserStatus currentStatus) 174 { 175 return ParserStatus::FUNCTION | ParserStatus::ARROW_FUNCTION | 176 static_cast<ParserStatus>(currentStatus & (ParserStatus::ALLOW_SUPER | ParserStatus::ALLOW_SUPER_CALL)); 177 } 178 }; 179 } // namespace ark::es2panda::parser 180 #endif 181