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
24namespace ark::es2panda::ir {
25class Literal;
26class TaggedTemplateExpression;
27}  // namespace ark::es2panda::ir
28
29namespace ark::es2panda::checker {
30class TSChecker;
31class Type;
32}  // namespace ark::es2panda::checker
33
34namespace ark::es2panda::compiler {
35constexpr auto INVALID_LITERAL_BUFFER_ID = std::numeric_limits<uint32_t>::max();
36
37// must be kept in sync with ark::panda_file::LiteralTag
38enum 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
55class Literal {
56public:
57    explicit Literal() = default;
58
59    explicit Literal(LiteralTag tag, const util::StringView &str) : tag_(tag), value_(str.Mutf8()) {}
60    explicit Literal(const util::StringView &str) : tag_(LiteralTag::STRING), value_(str.Mutf8()) {}
61    explicit Literal(uint32_t number) : tag_(LiteralTag::INTEGER), value_(number) {}
62    explicit Literal(double number) : tag_(LiteralTag::DOUBLE), value_(number) {}
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
69    static Literal NullLiteral()
70    {
71        return Literal(LiteralTag::NULL_VALUE);
72    }
73
74    static Literal UndefinedLiteral()
75    {
76        return Literal(LiteralTag::UNDEFINED_VALUE);
77    }
78
79    static Literal AccessorLiteral()
80    {
81        return Literal(LiteralTag::ACCESSOR);
82    }
83
84    LiteralTag Tag() const
85    {
86        return tag_;
87    }
88
89    bool IsTagMethod() const
90    {
91        return tag_ >= LiteralTag::METHOD;
92    }
93
94    const std::string &GetString() const
95    {
96        return std::get<std::string>(value_);
97    }
98
99    uint32_t GetInteger() const
100    {
101        return std::get<uint32_t>(value_);
102    }
103
104    double GetDouble() const
105    {
106        return std::get<double>(value_);
107    }
108
109    bool GetBoolean() const
110    {
111        return static_cast<bool>(std::get<uint32_t>(value_));
112    }
113
114    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
122    bool IsInvalid() const
123    {
124        return tag_ == LiteralTag::INVALID;
125    }
126
127private:
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
134class PandaGen;
135
136using LiteralBuffer = std::vector<Literal>;
137
138class Literals {
139public:
140    Literals() = delete;
141
142    static void GetTemplateObject(PandaGen *pg, const ir::TaggedTemplateExpression *lit);
143};
144}  // namespace ark::es2panda::compiler
145
146#endif
147