• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 #include "ETSLexer.h"
17 #include "generated/keywords.h"
18 
19 namespace ark::es2panda::lexer {
20 // NOLINTNEXTLINE(google-default-arguments)
NextToken(NextTokenFlags flags)21 void ETSLexer::NextToken(NextTokenFlags flags)
22 {
23     ETSKeywords kws(this, static_cast<NextTokenFlags>(flags & ~NextTokenFlags::KEYWORD_TO_IDENT));
24     Lexer::NextToken(&kws);
25 }
26 
ScanHashMark()27 void ETSLexer::ScanHashMark()
28 {
29     LogError(diagnostic::ERROR_ARKTS_NO_PRIVATE_IDENTIFIERS);
30 }
31 
ScanCharLiteral()32 bool ETSLexer::ScanCharLiteral()
33 {
34     //  Note: for character literal on call iterator is pointed to the opening single quote (') character!
35     //  Otherwise it's another token.
36     bool status = true;
37 
38     if (Iterator().Peek() != LEX_CHAR_SINGLE_QUOTE) {
39         return false;
40     }
41 
42     GetToken().type_ = TokenType::LITERAL_CHAR;
43 
44     Iterator().Forward(1);
45     char32_t cp = Iterator().PeekCp();
46 
47     switch (cp) {
48         case LEX_CHAR_SINGLE_QUOTE:
49         case util::StringView::Iterator::INVALID_CP: {
50             LogError(diagnostic::INVALID_CHAR);
51             status = false;
52             break;
53         }
54         case LEX_CHAR_BACKSLASH: {
55             GetToken().flags_ |= TokenFlags::HAS_ESCAPE;
56 
57             Iterator().Forward(1);
58             cp = ScanUnicodeCharacter();
59             break;
60         }
61         default: {
62             Iterator().SkipCp();
63             break;
64         }
65     }
66 
67     if (CheckUtf16Compatible(cp)) {
68         GetToken().c16_ = cp;
69     }
70 
71     if (Iterator().Peek() != LEX_CHAR_SINGLE_QUOTE) {
72         LogError(diagnostic::UNSUPPORTED_CHAR_LIT);
73         return false;
74     }
75 
76     Iterator().Forward(1);
77     return status;
78 }
79 
CheckNumberLiteralEnd()80 void ETSLexer::CheckNumberLiteralEnd()
81 {
82     if (Iterator().Peek() == LEX_CHAR_LOWERCASE_F) {
83         GetToken().flags_ |= TokenFlags::NUMBER_FLOAT;
84         GetToken().src_ = SourceView(GetToken().Start().index, Iterator().Index());
85         Iterator().Forward(1);
86         const auto nextCp = Iterator().PeekCp();
87         if (KeywordsUtil::IsIdentifierStart(nextCp) || IsDecimalDigit(nextCp)) {
88             LogError(diagnostic::INVALID_NUMERIC_LIT);
89             Iterator().Forward(1);  // Error processing
90         }
91     } else {
92         Lexer::CheckNumberLiteralEnd();
93     }
94 }
95 
CheckUtf16Compatible(char32_t cp) const96 bool ETSLexer::CheckUtf16Compatible(char32_t cp) const
97 {
98     if (cp >= util::StringView::Constants::CELESTIAL_OFFSET) {
99         // lexer_invalid_characters.ets
100         LogError(diagnostic::UNSUPPORTED_CHAR_LIT);
101         return false;
102     }
103     return true;
104 }
105 
ScanAsteriskPunctuator()106 void ETSLexer::ScanAsteriskPunctuator()
107 {
108     GetToken().type_ = TokenType::PUNCTUATOR_MULTIPLY;
109     auto cp = Iterator().Peek();
110     if (cp == LEX_CHAR_EQUALS) {
111         GetToken().type_ = TokenType::PUNCTUATOR_MULTIPLY_EQUAL;
112         Iterator().Forward(1);
113         return;
114     }
115 
116     Iterator().Backward(1);
117     if (!IsValidJsDocEnd(&cp)) {
118         Iterator().Forward(1);
119         return;
120     }
121     Iterator().Forward(JS_DOC_END_SIZE + 1);
122     GetToken().type_ = TokenType::JS_DOC_END;
123     Pos().NextTokenLine() += 1;
124 }
125 
ConvertNumber(NumberFlags const flags)126 void ETSLexer::ConvertNumber(NumberFlags const flags)
127 {
128     GetToken().number_ = lexer::Number(GetToken().src_, flags);
129     if (GetToken().number_.ConversionError()) {
130         LogError(diagnostic::INVALID_NUM);
131     }
132 }
133 
ScanEqualsPunctuator()134 void ETSLexer::ScanEqualsPunctuator()
135 {
136     GetToken().type_ = TokenType::PUNCTUATOR_SUBSTITUTION;
137 
138     switch (Iterator().Peek()) {
139         case LEX_CHAR_EQUALS: {
140             GetToken().type_ = TokenType::PUNCTUATOR_EQUAL;
141             Iterator().Forward(1);
142 
143             if (Iterator().Peek() == LEX_CHAR_EQUALS) {
144                 GetToken().type_ = TokenType::PUNCTUATOR_STRICT_EQUAL;
145                 Iterator().Forward(1);
146             }
147             break;
148         }
149         case LEX_CHAR_GREATER_THAN: {
150             GetToken().type_ = TokenType::PUNCTUATOR_ARROW;
151             Iterator().Forward(1);
152             break;
153         }
154         default: {
155             break;
156         }
157     }
158 }
159 
ScanExclamationPunctuator()160 void ETSLexer::ScanExclamationPunctuator()
161 {
162     GetToken().type_ = TokenType::PUNCTUATOR_EXCLAMATION_MARK;
163 
164     switch (Iterator().Peek()) {
165         case LEX_CHAR_EQUALS: {
166             GetToken().type_ = TokenType::PUNCTUATOR_NOT_EQUAL;
167             Iterator().Forward(1);
168 
169             if (Iterator().Peek() == LEX_CHAR_EQUALS) {
170                 GetToken().type_ = TokenType::PUNCTUATOR_NOT_STRICT_EQUAL;
171                 Iterator().Forward(1);
172             }
173             break;
174         }
175         default: {
176             break;
177         }
178     }
179 }
180 
181 }  // namespace ark::es2panda::lexer
182