1/**
2 * Copyright (c) 2021 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_PARSER_CORE_TOKEN_H
17#define ES2PANDA_PARSER_CORE_TOKEN_H
18
19#include <lexer/token/sourceLocation.h>
20#include <lexer/token/tokenType.h>
21#include <macros.h>
22#include <util/enumbitops.h>
23#include <util/ustring.h>
24
25namespace panda::es2panda::lexer {
26
27enum class TokenFlags : uint8_t {
28    NONE,
29    NEW_LINE = (1 << 0),
30    HAS_ESCAPE = (1 << 2),
31    NUMBER_BIGINT = (1 << 3),
32    NUMBER_HAS_UNDERSCORE = (1 << 4),
33    ESCAPE_ERROR = (1 << 5),
34    TAGGED_TEMPLATE = (1 << 6),
35};
36
37DEFINE_BITOPS(TokenFlags)
38
39class Token {
40public:
41    Token() = default;
42    DEFAULT_COPY_SEMANTIC(Token);
43    DEFAULT_MOVE_SEMANTIC(Token);
44    ~Token() = default;
45
46    friend class Lexer;
47
48    TokenType Type() const
49    {
50        return type_;
51    }
52
53    TokenFlags Flags() const
54    {
55        return flags_;
56    }
57
58    void SetTokenType(TokenType type)
59    {
60        type_ = type;
61    }
62
63    TokenType KeywordType() const
64    {
65        return keywordType_;
66    }
67
68    const SourcePosition &Start() const
69    {
70        return loc_.start;
71    }
72
73    const SourcePosition &End() const
74    {
75        return loc_.end;
76    }
77
78    const SourceRange &Loc() const
79    {
80        return loc_;
81    }
82
83    const util::StringView &Ident() const
84    {
85        return src_;
86    }
87
88    const util::StringView &BigInt() const
89    {
90        ASSERT(type_ == TokenType::LITERAL_NUMBER && (flags_ & TokenFlags::NUMBER_BIGINT));
91        return src_;
92    }
93
94    double Number() const
95    {
96        ASSERT(type_ == TokenType::LITERAL_NUMBER && !(flags_ & TokenFlags::NUMBER_BIGINT));
97        return number_;
98    }
99
100    const util::StringView &String() const
101    {
102        ASSERT(type_ == TokenType::LITERAL_STRING || type_ == TokenType::LITERAL_NUMBER);
103        return src_;
104    }
105
106    bool NewLine() const
107    {
108        return flags_ & TokenFlags::NEW_LINE;
109    }
110
111    bool EscapeError() const
112    {
113        return flags_ & TokenFlags::ESCAPE_ERROR;
114    }
115
116    bool IsTaggedTemplate() const
117    {
118        return flags_ & TokenFlags::TAGGED_TEMPLATE;
119    }
120
121    bool IsAccessability() const;
122    bool IsAsyncModifier() const;
123    bool IsStaticModifier() const;
124    bool IsDeclareModifier() const;
125    bool IsReadonlyModifier() const;
126    bool IsAccessorModifier() const;
127    bool IsUpdate() const;
128    bool IsUnary() const;
129    bool IsPropNameLiteral() const;
130    bool IsKeyword() const;
131    bool IsReservedTypeName() const;
132    bool IsJsStrictReservedWord() const;
133
134    static bool IsBinaryToken(TokenType type);
135    static bool IsBinaryLvalueToken(TokenType type);
136    static bool IsUpdateToken(TokenType type);
137    static bool IsPunctuatorToken(TokenType type);
138    static bool IsTsParamToken(TokenType type, char32_t nextChar);
139
140private:
141    friend class KeywordsUtil;
142    TokenType type_ {TokenType::EOS};
143    TokenType keywordType_ {TokenType::EOS};
144    TokenFlags flags_ {TokenFlags::NONE};
145    SourceRange loc_ {};
146    double number_ {};
147    util::StringView src_ {};
148};
149
150}  // namespace panda::es2panda::lexer
151
152#endif /* TOKEN_H */
153