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 ES2PANDA_PARSER_CORE_KEYWORDS_UTIL_H
17#define ES2PANDA_PARSER_CORE_KEYWORDS_UTIL_H
18
19#include "lexer/keywordString.h"
20#include "lexer/lexer.h"
21#include "lexer/token/letters.h"
22#include "lexer/token/tokenType.h"
23#include "macros.h"
24#include "util/ustring.h"
25#include "utils/span.h"
26
27namespace ark::es2panda::lexer {
28class Lexer;
29class Keywords;
30
31class KeywordsUtil {
32public:
33    explicit KeywordsUtil(Lexer *lexer, lexer::NextTokenFlags flags) : lexer_(lexer), flags_(flags) {}
34    explicit KeywordsUtil(Lexer *lexer, lexer::NextTokenFlags flags, char32_t cp)
35        : lexer_(lexer), flags_(flags), cp_(cp)
36    {
37    }
38    NO_COPY_SEMANTIC(KeywordsUtil);
39    DEFAULT_MOVE_SEMANTIC(KeywordsUtil);
40    ~KeywordsUtil() = default;
41
42    inline bool HasEscape() const
43    {
44        return (lexer_->GetToken().flags_ & lexer::TokenFlags::HAS_ESCAPE) != 0;
45    }
46
47    const parser::ParserContext *GetParserContext() const
48    {
49        return lexer_->parserContext_;
50    }
51
52    [[noreturn]] void ThrowError(std::string_view msg) const
53    {
54        lexer_->ThrowError(msg);
55    }
56
57    [[noreturn]] void ThrowUnexpectedStrictModeReservedKeyword() const
58    {
59        lexer_->ThrowUnexpectedStrictModeReservedKeyword();
60    }
61
62    inline NextTokenFlags Flags() const
63    {
64        return flags_;
65    }
66
67    inline bool KeywordToIdent() const
68    {
69        return (flags_ & NextTokenFlags::KEYWORD_TO_IDENT) != 0;
70    }
71
72    inline void CheckEscapedKeyword() const
73    {
74        if (HasEscape()) {
75            ThrowEscapedKeyword();
76        }
77    }
78
79    inline void ThrowEscapedKeyword() const
80    {
81        ThrowError("Escape sequences are not allowed in keywords");
82    }
83
84    inline void SetKeyword(KeywordString kws) const
85    {
86        lexer_->GetToken().src_ = util::StringView(kws.Str());
87        lexer_->GetToken().type_ = kws.GetTokenType();
88        lexer_->GetToken().keywordType_ = kws.GetKeywordType();
89    }
90
91    inline util::StringView::Iterator &Iterator()
92    {
93        return lexer_->Iterator();
94    }
95
96    void ScanIdentifierStart(const Keywords *kws, char32_t cp);
97    void ScanIdContinue();
98
99    void ScanIdContinueMaybeKeyword(const Keywords *kws, Span<const KeywordString> map);
100    char32_t ScanUnicodeEscapeSequence();
101
102    static bool IsIdentifierStart(char32_t cp);
103    static bool IsIdentifierPart(char32_t cp);
104
105private:
106    Lexer *lexer_;
107    NextTokenFlags flags_ {};
108    char32_t cp_ {util::StringView::Iterator::INVALID_CP};
109};
110
111}  // namespace ark::es2panda::lexer
112
113#endif
114