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_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 panda::es2panda::lexer {
28
29class Lexer;
30
31class KeywordsUtil {
32public:
33    explicit KeywordsUtil(Lexer *lexer, lexer::LexerNextTokenFlags flags) : lexer_(lexer), flags_(flags) {}
34    explicit KeywordsUtil(Lexer *lexer, lexer::LexerNextTokenFlags 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    template <TokenType keyword_type>
48    inline void SetKeyword(std::string_view str, TokenType type);
49
50    inline util::StringView::Iterator &Iterator()
51    {
52        return lexer_->Iterator();
53    }
54
55    void ScanIdentifierStart(char32_t cp);
56    void ScanIdContinue();
57
58    void ScanIdContinueMaybeKeyword(Span<const KeywordString> map);
59    char32_t ScanUnicodeEscapeSequence();
60
61    static bool IsIdentifierStart(char32_t cp);
62    static bool IsIdentifierPart(char32_t cp);
63
64private:
65    Lexer *lexer_;
66    lexer::LexerNextTokenFlags flags_ {};
67    char32_t cp_ {util::StringView::Iterator::INVALID_CP};
68};
69
70template <TokenType keyword_type>
71inline void KeywordsUtil::SetKeyword(std::string_view str, TokenType type)
72{
73    lexer_->GetToken().src_ = util::StringView(str);
74    // NOLINTNEXTLINE
75    lexer_->GetToken().keywordType_ = keyword_type;
76
77    if (flags_ & lexer::LexerNextTokenFlags::KEYWORD_TO_IDENT) {
78        lexer_->GetToken().type_ = TokenType::LITERAL_IDENT;
79    } else {
80        // NOLINTNEXTLINE
81        lexer_->CheckKeyword<keyword_type>(type, flags_);
82    }
83}
84
85}  // namespace panda::es2panda::lexer
86
87#endif
88