• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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     LogUnexpectedToken(TokenType::PUNCTUATOR_HASH_MARK);
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             LogSyntaxError("Invalid character literal");
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         LogSyntaxError("Unterminated character literal");
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             LogSyntaxError("Invalid numeric literal");
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.sts
100         LogSyntaxError("Unsupported character literal");
101         return false;
102     }
103     return true;
104 }
105 
ScanAsteriskPunctuator()106 void ETSLexer::ScanAsteriskPunctuator()
107 {
108     GetToken().type_ = TokenType::PUNCTUATOR_MULTIPLY;
109 
110     switch (Iterator().Peek()) {
111         case LEX_CHAR_EQUALS: {
112             GetToken().type_ = TokenType::PUNCTUATOR_MULTIPLY_EQUAL;
113             Iterator().Forward(1);
114             break;
115         }
116         default: {
117             break;
118         }
119     }
120 }
121 
ConvertNumber(NumberFlags const flags)122 void ETSLexer::ConvertNumber(NumberFlags const flags)
123 {
124     GetToken().number_ = lexer::Number(GetToken().src_, flags);
125     if (GetToken().number_.ConversionError()) {
126         LogSyntaxError("Invalid number");
127     }
128 }
129 
ScanEqualsPunctuator()130 void ETSLexer::ScanEqualsPunctuator()
131 {
132     GetToken().type_ = TokenType::PUNCTUATOR_SUBSTITUTION;
133 
134     switch (Iterator().Peek()) {
135         case LEX_CHAR_EQUALS: {
136             GetToken().type_ = TokenType::PUNCTUATOR_EQUAL;
137             Iterator().Forward(1);
138 
139             if (Iterator().Peek() == LEX_CHAR_EQUALS) {
140                 GetToken().type_ = TokenType::PUNCTUATOR_STRICT_EQUAL;
141                 Iterator().Forward(1);
142             }
143             break;
144         }
145         case LEX_CHAR_GREATER_THAN: {
146             GetToken().type_ = TokenType::PUNCTUATOR_ARROW;
147             Iterator().Forward(1);
148             break;
149         }
150         default: {
151             break;
152         }
153     }
154 }
155 
ScanExclamationPunctuator()156 void ETSLexer::ScanExclamationPunctuator()
157 {
158     GetToken().type_ = TokenType::PUNCTUATOR_EXCLAMATION_MARK;
159 
160     switch (Iterator().Peek()) {
161         case LEX_CHAR_EQUALS: {
162             GetToken().type_ = TokenType::PUNCTUATOR_NOT_EQUAL;
163             Iterator().Forward(1);
164 
165             if (Iterator().Peek() == LEX_CHAR_EQUALS) {
166                 GetToken().type_ = TokenType::PUNCTUATOR_NOT_STRICT_EQUAL;
167                 Iterator().Forward(1);
168             }
169             break;
170         }
171         default: {
172             break;
173         }
174     }
175 }
176 
ScanDollarPunctuator()177 bool ETSLexer::ScanDollarPunctuator()
178 {
179     if (Iterator().Peek() != LEX_CHAR_DOLLAR_SIGN) {
180         return false;
181     }
182 
183     GetToken().type_ = TokenType::PUNCTUATOR_DOLLAR_DOLLAR;
184     Iterator().Forward(1);
185     return true;
186 }
187 }  // namespace ark::es2panda::lexer
188