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)21void ETSLexer::NextToken(NextTokenFlags flags) 22 { 23 ETSKeywords kws(this, static_cast<NextTokenFlags>(flags & ~NextTokenFlags::KEYWORD_TO_IDENT)); 24 Lexer::NextToken(&kws); 25 } 26 ScanHashMark()27void ETSLexer::ScanHashMark() 28 { 29 LogError(diagnostic::ERROR_ARKTS_NO_PRIVATE_IDENTIFIERS); 30 } 31 ScanCharLiteral()32bool 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()80void 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) const96bool 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()106void 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)126void 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()134void 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()160void 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