1 /*
2  * Copyright (c) 2021 - 2023 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_COMPILER_BASE_LITERALS_H
17 #define ES2PANDA_COMPILER_BASE_LITERALS_H
18 
19 #include "ir/expressions/literal.h"
20 #include "util/ustring.h"
21 
22 #include <variant>
23 
24 namespace ark::es2panda::ir {
25 class Literal;
26 class TaggedTemplateExpression;
27 }  // namespace ark::es2panda::ir
28 
29 namespace ark::es2panda::checker {
30 class TSChecker;
31 class Type;
32 }  // namespace ark::es2panda::checker
33 
34 namespace ark::es2panda::compiler {
35 constexpr auto INVALID_LITERAL_BUFFER_ID = std::numeric_limits<uint32_t>::max();
36 
37 // must be kept in sync with ark::panda_file::LiteralTag
38 enum class LiteralTag {
39     INVALID,
40     TAGVALUE,
41     BOOLEAN,
42     INTEGER,
43     FLOAT,
44     DOUBLE,
45     STRING,
46     NULL_VALUE,
47     UNDEFINED_VALUE,
48     ACCESSOR,
49     METHOD,
50     GENERATOR_METHOD,
51     ASYNC_METHOD,
52     ASYNC_GENERATOR_METHOD,
53 };
54 
55 class Literal {
56 public:
57     explicit Literal() = default;
58 
Literal(LiteralTag tag, const util::StringView &str)59     explicit Literal(LiteralTag tag, const util::StringView &str) : tag_(tag), value_(str.Mutf8()) {}
Literal(const util::StringView &str)60     explicit Literal(const util::StringView &str) : tag_(LiteralTag::STRING), value_(str.Mutf8()) {}
Literal(uint32_t number)61     explicit Literal(uint32_t number) : tag_(LiteralTag::INTEGER), value_(number) {}
Literal(double number)62     explicit Literal(double number) : tag_(LiteralTag::DOUBLE), value_(number) {}
Literal(bool boolean)63     explicit Literal(bool boolean) : tag_(LiteralTag::BOOLEAN), value_(static_cast<uint32_t>(boolean)) {}
64 
65     DEFAULT_COPY_SEMANTIC(Literal);
66     DEFAULT_MOVE_SEMANTIC(Literal);
67     ~Literal() = default;
68 
NullLiteral()69     static Literal NullLiteral()
70     {
71         return Literal(LiteralTag::NULL_VALUE);
72     }
73 
UndefinedLiteral()74     static Literal UndefinedLiteral()
75     {
76         return Literal(LiteralTag::UNDEFINED_VALUE);
77     }
78 
AccessorLiteral()79     static Literal AccessorLiteral()
80     {
81         return Literal(LiteralTag::ACCESSOR);
82     }
83 
Tag() const84     LiteralTag Tag() const
85     {
86         return tag_;
87     }
88 
IsTagMethod() const89     bool IsTagMethod() const
90     {
91         return tag_ >= LiteralTag::METHOD;
92     }
93 
GetString() const94     const std::string &GetString() const
95     {
96         return std::get<std::string>(value_);
97     }
98 
GetInteger() const99     uint32_t GetInteger() const
100     {
101         return std::get<uint32_t>(value_);
102     }
103 
GetDouble() const104     double GetDouble() const
105     {
106         return std::get<double>(value_);
107     }
108 
GetBoolean() const109     bool GetBoolean() const
110     {
111         return static_cast<bool>(std::get<uint32_t>(value_));
112     }
113 
GetMethod() const114     std::string GetMethod() const
115     {
116         ASSERT(tag_ == LiteralTag::ACCESSOR || tag_ == LiteralTag::METHOD || tag_ == LiteralTag::GENERATOR_METHOD ||
117                tag_ == LiteralTag::ASYNC_METHOD || tag_ == LiteralTag::ASYNC_GENERATOR_METHOD);
118 
119         return std::get<std::string>(value_);
120     }
121 
IsInvalid() const122     bool IsInvalid() const
123     {
124         return tag_ == LiteralTag::INVALID;
125     }
126 
127 private:
Literal(LiteralTag tag)128     explicit Literal(LiteralTag tag) : tag_(tag) {}
129 
130     LiteralTag tag_ {LiteralTag::INVALID};
131     std::variant<std::string, double, uint32_t> value_ {static_cast<uint32_t>(0)};
132 };
133 
134 class PandaGen;
135 
136 using LiteralBuffer = std::vector<Literal>;
137 
138 class Literals {
139 public:
140     Literals() = delete;
141 
142     static void GetTemplateObject(PandaGen *pg, const ir::TaggedTemplateExpression *lit);
143 };
144 }  // namespace ark::es2panda::compiler
145 
146 #endif
147