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 19namespace ark::es2panda::lexer { 20// NOLINTNEXTLINE(google-default-arguments) 21void ETSLexer::NextToken(NextTokenFlags flags) 22{ 23 ETSKeywords kws(this, static_cast<NextTokenFlags>(flags & ~NextTokenFlags::KEYWORD_TO_IDENT)); 24 Lexer::NextToken(&kws); 25} 26 27void ETSLexer::ScanHashMark() 28{ 29 ThrowUnexpectedToken(TokenType::PUNCTUATOR_HASH_MARK); 30} 31 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 if (Iterator().Peek() != LEX_CHAR_SINGLE_QUOTE) { 37 return false; 38 } 39 40 GetToken().type_ = TokenType::LITERAL_CHAR; 41 42 Iterator().Forward(1); 43 char32_t cp = Iterator().PeekCp(); 44 45 switch (cp) { 46 case LEX_CHAR_SINGLE_QUOTE: 47 case util::StringView::Iterator::INVALID_CP: { 48 ThrowError("Invalid character literal"); 49 break; 50 } 51 case LEX_CHAR_BACKSLASH: { 52 GetToken().flags_ |= TokenFlags::HAS_ESCAPE; 53 54 Iterator().Forward(1); 55 cp = ScanUnicodeCharacter(); 56 break; 57 } 58 default: { 59 Iterator().SkipCp(); 60 break; 61 } 62 } 63 64 CheckUtf16Compatible(cp); 65 GetToken().c16_ = cp; 66 67 if (Iterator().Peek() != LEX_CHAR_SINGLE_QUOTE) { 68 ThrowError("Unterminated character literal"); 69 } 70 71 Iterator().Forward(1); 72 return true; 73} 74 75void ETSLexer::CheckNumberLiteralEnd() 76{ 77 if (Iterator().Peek() == LEX_CHAR_LOWERCASE_F) { 78 GetToken().flags_ |= TokenFlags::NUMBER_FLOAT; 79 GetToken().src_ = SourceView(GetToken().Start().index, Iterator().Index()); 80 Iterator().Forward(1); 81 const auto nextCp = Iterator().PeekCp(); 82 if (KeywordsUtil::IsIdentifierStart(nextCp) || IsDecimalDigit(nextCp)) { 83 ThrowError("Invalid numeric literal"); 84 } 85 } else { 86 Lexer::CheckNumberLiteralEnd(); 87 } 88} 89 90void ETSLexer::CheckUtf16Compatible(char32_t cp) const 91{ 92 if (cp >= util::StringView::Constants::CELESTIAL_OFFSET) { 93 ThrowError("Unsupported character literal"); 94 } 95} 96 97void ETSLexer::ScanAsteriskPunctuator() 98{ 99 GetToken().type_ = TokenType::PUNCTUATOR_MULTIPLY; 100 101 switch (Iterator().Peek()) { 102 case LEX_CHAR_EQUALS: { 103 GetToken().type_ = TokenType::PUNCTUATOR_MULTIPLY_EQUAL; 104 Iterator().Forward(1); 105 break; 106 } 107 default: { 108 break; 109 } 110 } 111} 112 113void ETSLexer::ConvertNumber(const std::string &utf8, NumberFlags flags) 114{ 115 GetToken().number_ = lexer::Number(GetToken().src_, utf8, flags); 116 117 if (GetToken().number_.ConversionError()) { 118 ThrowError("Invalid number"); 119 } 120} 121 122void ETSLexer::ScanEqualsPunctuator() 123{ 124 GetToken().type_ = TokenType::PUNCTUATOR_SUBSTITUTION; 125 126 switch (Iterator().Peek()) { 127 case LEX_CHAR_EQUALS: { 128 GetToken().type_ = TokenType::PUNCTUATOR_EQUAL; 129 Iterator().Forward(1); 130 131 if (Iterator().Peek() == LEX_CHAR_EQUALS) { 132 GetToken().type_ = TokenType::PUNCTUATOR_STRICT_EQUAL; 133 Iterator().Forward(1); 134 } 135 break; 136 } 137 case LEX_CHAR_GREATER_THAN: { 138 GetToken().type_ = TokenType::PUNCTUATOR_ARROW; 139 Iterator().Forward(1); 140 break; 141 } 142 default: { 143 break; 144 } 145 } 146} 147 148void ETSLexer::ScanExclamationPunctuator() 149{ 150 GetToken().type_ = TokenType::PUNCTUATOR_EXCLAMATION_MARK; 151 152 switch (Iterator().Peek()) { 153 case LEX_CHAR_EQUALS: { 154 GetToken().type_ = TokenType::PUNCTUATOR_NOT_EQUAL; 155 Iterator().Forward(1); 156 157 if (Iterator().Peek() == LEX_CHAR_EQUALS) { 158 GetToken().type_ = TokenType::PUNCTUATOR_NOT_STRICT_EQUAL; 159 Iterator().Forward(1); 160 } 161 break; 162 } 163 default: { 164 break; 165 } 166 } 167} 168 169bool ETSLexer::ScanDollarPunctuator() 170{ 171 if (Iterator().Peek() != LEX_CHAR_DOLLAR_SIGN) { 172 return false; 173 } 174 175 GetToken().type_ = TokenType::PUNCTUATOR_DOLLAR_DOLLAR; 176 Iterator().Forward(1); 177 return true; 178} 179} // namespace ark::es2panda::lexer 180