OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 | 128 |
129 #define CHECK_OK_CUSTOM(x) ok); \ | 129 #define CHECK_OK_CUSTOM(x) ok); \ |
130 if (!*ok) return this->x(); \ | 130 if (!*ok) return this->x(); \ |
131 ((void)0 | 131 ((void)0 |
132 #define DUMMY ) // to make indentation work | 132 #define DUMMY ) // to make indentation work |
133 #undef DUMMY | 133 #undef DUMMY |
134 | 134 |
135 // Used in functions where the return type is ExpressionT. | 135 // Used in functions where the return type is ExpressionT. |
136 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) | 136 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) |
137 | 137 |
| 138 // Common base class template shared between parser and pre-parser. |
| 139 // The Impl parameter is the actual class of the parser/pre-parser, |
| 140 // following the Curiously Recurring Template Pattern (CRTP). |
| 141 // The structure of the parser objects is roughly the following: |
| 142 // |
| 143 // // Common denominator, needed to avoid cyclic dependency. |
| 144 // // Instances of this template will end up with very minimal |
| 145 // // definitions, ideally containing just typedefs. |
| 146 // template <typename Impl> |
| 147 // class ParserBaseTraits; |
138 | 148 |
139 // Common base class shared between parser and pre-parser. Traits encapsulate | 149 // // The parser base object, which should just implement pure |
140 // the differences between Parser and PreParser: | 150 // // parser behavior. The Impl parameter is the actual derived |
| 151 // // class (according to CRTP), which implements impure parser |
| 152 // // behavior. |
| 153 // template <typename Impl> |
| 154 // class ParserBase : public ParserBaseTraits<Impl> { ... }; |
| 155 // |
| 156 // // And then, for each parser variant (e.g., parser, preparser, etc): |
| 157 // class Parser; |
| 158 // |
| 159 // template <> |
| 160 // class ParserBaseTraits<Parser> { ... }; |
| 161 // |
| 162 // class Parser : public ParserBase<Parser> { ... }; |
| 163 // |
| 164 // TODO(nikolaos): Currently the traits objects contain many things |
| 165 // that will be moved to the implementation objects or to the parser |
| 166 // base. The following comments will have to change, when this happens. |
| 167 |
| 168 // The traits class template encapsulates the differences between |
| 169 // parser/pre-parser implementations. In particular: |
141 | 170 |
142 // - Return types: For example, Parser functions return Expression* and | 171 // - Return types: For example, Parser functions return Expression* and |
143 // PreParser functions return PreParserExpression. | 172 // PreParser functions return PreParserExpression. |
144 | 173 |
145 // - Creating parse tree nodes: Parser generates an AST during the recursive | 174 // - Creating parse tree nodes: Parser generates an AST during the recursive |
146 // descent. PreParser doesn't create a tree. Instead, it passes around minimal | 175 // descent. PreParser doesn't create a tree. Instead, it passes around minimal |
147 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain | 176 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain |
148 // just enough data for the upper layer functions. PreParserFactory is | 177 // just enough data for the upper layer functions. PreParserFactory is |
149 // responsible for creating these dummy objects. It provides a similar kind of | 178 // responsible for creating these dummy objects. It provides a similar kind of |
150 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is | 179 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is |
151 // used. | 180 // used. |
152 | 181 |
153 // - Miscellaneous other tasks interleaved with the recursive descent. For | 182 // - Miscellaneous other tasks interleaved with the recursive descent. For |
154 // example, Parser keeps track of which function literals should be marked as | 183 // example, Parser keeps track of which function literals should be marked as |
155 // pretenured, and PreParser doesn't care. | 184 // pretenured, and PreParser doesn't care. |
156 | 185 |
157 // The traits are expected to contain the following typedefs: | 186 // The traits are expected to contain the following typedefs: |
158 // struct Traits { | 187 // template <> |
| 188 // class ParserBaseTraits<Impl> { |
159 // // In particular... | 189 // // In particular... |
160 // struct Type { | 190 // struct Type { |
161 // // Used by FunctionState and BlockState. | |
162 // typedef Scope; | |
163 // typedef GeneratorVariable; | 191 // typedef GeneratorVariable; |
| 192 // typedef AstProperties; |
| 193 // typedef ExpressionClassifier; |
164 // // Return types for traversing functions. | 194 // // Return types for traversing functions. |
165 // typedef Identifier; | 195 // typedef Identifier; |
166 // typedef Expression; | 196 // typedef Expression; |
| 197 // typedef YieldExpression; |
167 // typedef FunctionLiteral; | 198 // typedef FunctionLiteral; |
168 // typedef ClassLiteral; | 199 // typedef ClassLiteral; |
| 200 // typedef Literal; |
169 // typedef ObjectLiteralProperty; | 201 // typedef ObjectLiteralProperty; |
170 // typedef Literal; | |
171 // typedef ExpressionList; | 202 // typedef ExpressionList; |
172 // typedef PropertyList; | 203 // typedef PropertyList; |
173 // typedef FormalParameter; | 204 // typedef FormalParameter; |
174 // typedef FormalParameters; | 205 // typedef FormalParameters; |
| 206 // typedef StatementList; |
175 // // For constructing objects returned by the traversing functions. | 207 // // For constructing objects returned by the traversing functions. |
176 // typedef Factory; | 208 // typedef Factory; |
177 // }; | 209 // }; |
178 // // ... | 210 // // ... |
179 // }; | 211 // }; |
180 | 212 |
181 template <typename Traits> | 213 template <typename Impl> |
182 class ParserBase : public Traits { | 214 class ParserBaseTraits; |
| 215 |
| 216 template <typename Impl> |
| 217 class ParserBase : public ParserBaseTraits<Impl> { |
183 public: | 218 public: |
184 // Shorten type names defined by Traits. | 219 // Shorten type names defined by Traits. |
| 220 typedef ParserBaseTraits<Impl> Traits; |
185 typedef typename Traits::Type::Expression ExpressionT; | 221 typedef typename Traits::Type::Expression ExpressionT; |
186 typedef typename Traits::Type::Identifier IdentifierT; | 222 typedef typename Traits::Type::Identifier IdentifierT; |
187 typedef typename Traits::Type::FormalParameter FormalParameterT; | 223 typedef typename Traits::Type::FormalParameter FormalParameterT; |
188 typedef typename Traits::Type::FormalParameters FormalParametersT; | 224 typedef typename Traits::Type::FormalParameters FormalParametersT; |
189 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | 225 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
190 typedef typename Traits::Type::Literal LiteralT; | 226 typedef typename Traits::Type::Literal LiteralT; |
191 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; | 227 typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT; |
192 typedef typename Traits::Type::StatementList StatementListT; | 228 typedef typename Traits::Type::StatementList StatementListT; |
193 typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier; | 229 typedef typename Traits::Type::ExpressionClassifier ExpressionClassifier; |
194 | 230 |
| 231 // All implementation-specific methods must be called through this. |
| 232 Impl* impl() { return static_cast<Impl*>(this); } |
| 233 const Impl* impl() const { return static_cast<const Impl*>(this); } |
| 234 |
195 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 235 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
196 v8::Extension* extension, AstValueFactory* ast_value_factory, | 236 v8::Extension* extension, AstValueFactory* ast_value_factory, |
197 ParserRecorder* log, typename Traits::Type::Parser this_object) | 237 ParserRecorder* log) |
198 : Traits(this_object), | 238 : scope_state_(nullptr), |
199 scope_state_(nullptr), | |
200 function_state_(nullptr), | 239 function_state_(nullptr), |
201 extension_(extension), | 240 extension_(extension), |
202 fni_(nullptr), | 241 fni_(nullptr), |
203 ast_value_factory_(ast_value_factory), | 242 ast_value_factory_(ast_value_factory), |
204 ast_node_factory_(ast_value_factory), | 243 ast_node_factory_(ast_value_factory), |
205 log_(log), | 244 log_(log), |
206 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 245 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
207 parsing_module_(false), | 246 parsing_module_(false), |
208 stack_limit_(stack_limit), | 247 stack_limit_(stack_limit), |
209 zone_(zone), | 248 zone_(zone), |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 ZoneList<typename ExpressionClassifier::Error> reported_errors_; | 547 ZoneList<typename ExpressionClassifier::Error> reported_errors_; |
509 | 548 |
510 // If true, the next (and immediately following) function literal is | 549 // If true, the next (and immediately following) function literal is |
511 // preceded by a parenthesis. | 550 // preceded by a parenthesis. |
512 bool next_function_is_parenthesized_; | 551 bool next_function_is_parenthesized_; |
513 | 552 |
514 // The value of the parents' next_function_is_parenthesized_, as it applies | 553 // The value of the parents' next_function_is_parenthesized_, as it applies |
515 // to this function. Filled in by constructor. | 554 // to this function. Filled in by constructor. |
516 bool this_function_is_parenthesized_; | 555 bool this_function_is_parenthesized_; |
517 | 556 |
518 friend class ParserTraits; | 557 friend class ParserBaseTraits<Impl>; |
519 friend class PreParserTraits; | |
520 friend class Checkpoint; | 558 friend class Checkpoint; |
521 }; | 559 }; |
522 | 560 |
523 // This scope sets current ReturnExprContext to given value. | 561 // This scope sets current ReturnExprContext to given value. |
524 class ReturnExprScope { | 562 class ReturnExprScope { |
525 public: | 563 public: |
526 explicit ReturnExprScope(FunctionState* function_state, | 564 explicit ReturnExprScope(FunctionState* function_state, |
527 ReturnExprContext return_expr_context) | 565 ReturnExprContext return_expr_context) |
528 : function_state_(function_state), | 566 : function_state_(function_state), |
529 sav_return_expr_context_(function_state->return_expr_context()) { | 567 sav_return_expr_context_(function_state->return_expr_context()) { |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 bool allow_harmony_do_expressions_; | 1306 bool allow_harmony_do_expressions_; |
1269 bool allow_harmony_for_in_; | 1307 bool allow_harmony_for_in_; |
1270 bool allow_harmony_function_sent_; | 1308 bool allow_harmony_function_sent_; |
1271 bool allow_harmony_async_await_; | 1309 bool allow_harmony_async_await_; |
1272 bool allow_harmony_restrictive_generators_; | 1310 bool allow_harmony_restrictive_generators_; |
1273 bool allow_harmony_trailing_commas_; | 1311 bool allow_harmony_trailing_commas_; |
1274 | 1312 |
1275 friend class DiscardableZoneScope; | 1313 friend class DiscardableZoneScope; |
1276 }; | 1314 }; |
1277 | 1315 |
1278 template <class Traits> | 1316 template <typename Impl> |
1279 ParserBase<Traits>::FunctionState::FunctionState( | 1317 ParserBase<Impl>::FunctionState::FunctionState( |
1280 FunctionState** function_state_stack, ScopeState** scope_stack, | 1318 FunctionState** function_state_stack, ScopeState** scope_stack, |
1281 Scope* scope, FunctionKind kind) | 1319 Scope* scope, FunctionKind kind) |
1282 : ScopeState(scope_stack, scope), | 1320 : ScopeState(scope_stack, scope), |
1283 next_materialized_literal_index_(0), | 1321 next_materialized_literal_index_(0), |
1284 expected_property_count_(0), | 1322 expected_property_count_(0), |
1285 kind_(kind), | 1323 kind_(kind), |
1286 generator_object_variable_(NULL), | 1324 generator_object_variable_(NULL), |
1287 function_state_stack_(function_state_stack), | 1325 function_state_stack_(function_state_stack), |
1288 outer_function_state_(*function_state_stack), | 1326 outer_function_state_(*function_state_stack), |
1289 destructuring_assignments_to_rewrite_(16, scope->zone()), | 1327 destructuring_assignments_to_rewrite_(16, scope->zone()), |
1290 tail_call_expressions_(scope->zone()), | 1328 tail_call_expressions_(scope->zone()), |
1291 return_expr_context_(ReturnExprContext::kInsideValidBlock), | 1329 return_expr_context_(ReturnExprContext::kInsideValidBlock), |
1292 non_patterns_to_rewrite_(0, scope->zone()), | 1330 non_patterns_to_rewrite_(0, scope->zone()), |
1293 reported_errors_(16, scope->zone()), | 1331 reported_errors_(16, scope->zone()), |
1294 next_function_is_parenthesized_(false), | 1332 next_function_is_parenthesized_(false), |
1295 this_function_is_parenthesized_(false) { | 1333 this_function_is_parenthesized_(false) { |
1296 *function_state_stack = this; | 1334 *function_state_stack = this; |
1297 if (outer_function_state_) { | 1335 if (outer_function_state_) { |
1298 this_function_is_parenthesized_ = | 1336 this_function_is_parenthesized_ = |
1299 outer_function_state_->next_function_is_parenthesized_; | 1337 outer_function_state_->next_function_is_parenthesized_; |
1300 outer_function_state_->next_function_is_parenthesized_ = false; | 1338 outer_function_state_->next_function_is_parenthesized_ = false; |
1301 } | 1339 } |
1302 } | 1340 } |
1303 | 1341 |
1304 | 1342 template <typename Impl> |
1305 template <class Traits> | 1343 ParserBase<Impl>::FunctionState::~FunctionState() { |
1306 ParserBase<Traits>::FunctionState::~FunctionState() { | |
1307 *function_state_stack_ = outer_function_state_; | 1344 *function_state_stack_ = outer_function_state_; |
1308 } | 1345 } |
1309 | 1346 |
1310 template <class Traits> | 1347 template <typename Impl> |
1311 void ParserBase<Traits>::GetUnexpectedTokenMessage( | 1348 void ParserBase<Impl>::GetUnexpectedTokenMessage( |
1312 Token::Value token, MessageTemplate::Template* message, | 1349 Token::Value token, MessageTemplate::Template* message, |
1313 Scanner::Location* location, const char** arg, | 1350 Scanner::Location* location, const char** arg, |
1314 MessageTemplate::Template default_) { | 1351 MessageTemplate::Template default_) { |
1315 *arg = nullptr; | 1352 *arg = nullptr; |
1316 switch (token) { | 1353 switch (token) { |
1317 case Token::EOS: | 1354 case Token::EOS: |
1318 *message = MessageTemplate::kUnexpectedEOS; | 1355 *message = MessageTemplate::kUnexpectedEOS; |
1319 break; | 1356 break; |
1320 case Token::SMI: | 1357 case Token::SMI: |
1321 case Token::NUMBER: | 1358 case Token::NUMBER: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 *message = MessageTemplate::kUnexpectedTokenRegExp; | 1396 *message = MessageTemplate::kUnexpectedTokenRegExp; |
1360 break; | 1397 break; |
1361 default: | 1398 default: |
1362 const char* name = Token::String(token); | 1399 const char* name = Token::String(token); |
1363 DCHECK(name != NULL); | 1400 DCHECK(name != NULL); |
1364 *arg = name; | 1401 *arg = name; |
1365 break; | 1402 break; |
1366 } | 1403 } |
1367 } | 1404 } |
1368 | 1405 |
1369 | 1406 template <typename Impl> |
1370 template <class Traits> | 1407 void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) { |
1371 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | |
1372 return ReportUnexpectedTokenAt(scanner_->location(), token); | 1408 return ReportUnexpectedTokenAt(scanner_->location(), token); |
1373 } | 1409 } |
1374 | 1410 |
1375 | 1411 template <typename Impl> |
1376 template <class Traits> | 1412 void ParserBase<Impl>::ReportUnexpectedTokenAt( |
1377 void ParserBase<Traits>::ReportUnexpectedTokenAt( | |
1378 Scanner::Location source_location, Token::Value token, | 1413 Scanner::Location source_location, Token::Value token, |
1379 MessageTemplate::Template message) { | 1414 MessageTemplate::Template message) { |
1380 const char* arg; | 1415 const char* arg; |
1381 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); | 1416 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); |
1382 Traits::ReportMessageAt(source_location, message, arg); | 1417 Traits::ReportMessageAt(source_location, message, arg); |
1383 } | 1418 } |
1384 | 1419 |
1385 | 1420 template <typename Impl> |
1386 template <class Traits> | 1421 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( |
1387 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | |
1388 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { | 1422 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { |
1389 ExpressionClassifier classifier(this); | 1423 ExpressionClassifier classifier(this); |
1390 auto result = | 1424 auto result = |
1391 ParseAndClassifyIdentifier(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | 1425 ParseAndClassifyIdentifier(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); |
1392 | 1426 |
1393 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { | 1427 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { |
1394 ValidateAssignmentPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | 1428 ValidateAssignmentPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); |
1395 ValidateBindingPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); | 1429 ValidateBindingPattern(&classifier, CHECK_OK_CUSTOM(EmptyIdentifier)); |
1396 } | 1430 } |
1397 | 1431 |
1398 return result; | 1432 return result; |
1399 } | 1433 } |
1400 | 1434 |
1401 | 1435 template <typename Impl> |
1402 template <class Traits> | 1436 typename ParserBase<Impl>::IdentifierT |
1403 typename ParserBase<Traits>::IdentifierT | 1437 ParserBase<Impl>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
1404 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1438 bool* ok) { |
1405 bool* ok) { | |
1406 Token::Value next = Next(); | 1439 Token::Value next = Next(); |
1407 if (next == Token::IDENTIFIER || next == Token::ASYNC || | 1440 if (next == Token::IDENTIFIER || next == Token::ASYNC || |
1408 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { | 1441 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { |
1409 IdentifierT name = this->GetSymbol(scanner()); | 1442 IdentifierT name = this->GetSymbol(scanner()); |
1410 // When this function is used to read a formal parameter, we don't always | 1443 // When this function is used to read a formal parameter, we don't always |
1411 // know whether the function is going to be strict or sloppy. Indeed for | 1444 // know whether the function is going to be strict or sloppy. Indeed for |
1412 // arrow functions we don't always know that the identifier we are reading | 1445 // arrow functions we don't always know that the identifier we are reading |
1413 // is actually a formal parameter. Therefore besides the errors that we | 1446 // is actually a formal parameter. Therefore besides the errors that we |
1414 // must detect because we know we're in strict mode, we also record any | 1447 // must detect because we know we're in strict mode, we also record any |
1415 // error that we might make in the future once we know the language mode. | 1448 // error that we might make in the future once we know the language mode. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1450 MessageTemplate::kLetInLexicalBinding); | 1483 MessageTemplate::kLetInLexicalBinding); |
1451 } | 1484 } |
1452 return this->GetSymbol(scanner()); | 1485 return this->GetSymbol(scanner()); |
1453 } else { | 1486 } else { |
1454 this->ReportUnexpectedToken(next); | 1487 this->ReportUnexpectedToken(next); |
1455 *ok = false; | 1488 *ok = false; |
1456 return Traits::EmptyIdentifier(); | 1489 return Traits::EmptyIdentifier(); |
1457 } | 1490 } |
1458 } | 1491 } |
1459 | 1492 |
1460 template <class Traits> | 1493 template <class Impl> |
1461 typename ParserBase<Traits>::IdentifierT | 1494 typename ParserBase<Impl>::IdentifierT |
1462 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( | 1495 ParserBase<Impl>::ParseIdentifierOrStrictReservedWord( |
1463 FunctionKind function_kind, bool* is_strict_reserved, bool* ok) { | 1496 FunctionKind function_kind, bool* is_strict_reserved, bool* ok) { |
1464 Token::Value next = Next(); | 1497 Token::Value next = Next(); |
1465 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ && | 1498 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ && |
1466 !IsAsyncFunction(function_kind)) || | 1499 !IsAsyncFunction(function_kind)) || |
1467 next == Token::ASYNC) { | 1500 next == Token::ASYNC) { |
1468 *is_strict_reserved = false; | 1501 *is_strict_reserved = false; |
1469 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1502 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
1470 next == Token::STATIC || | 1503 next == Token::STATIC || |
1471 (next == Token::YIELD && !IsGeneratorFunction(function_kind))) { | 1504 (next == Token::YIELD && !IsGeneratorFunction(function_kind))) { |
1472 *is_strict_reserved = true; | 1505 *is_strict_reserved = true; |
1473 } else { | 1506 } else { |
1474 ReportUnexpectedToken(next); | 1507 ReportUnexpectedToken(next); |
1475 *ok = false; | 1508 *ok = false; |
1476 return Traits::EmptyIdentifier(); | 1509 return Traits::EmptyIdentifier(); |
1477 } | 1510 } |
1478 | 1511 |
1479 return this->GetSymbol(scanner()); | 1512 return this->GetSymbol(scanner()); |
1480 } | 1513 } |
1481 | 1514 |
1482 template <class Traits> | 1515 template <typename Impl> |
1483 typename ParserBase<Traits>::IdentifierT | 1516 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName( |
1484 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1517 bool* ok) { |
1485 Token::Value next = Next(); | 1518 Token::Value next = Next(); |
1486 if (next != Token::IDENTIFIER && next != Token::ASYNC && | 1519 if (next != Token::IDENTIFIER && next != Token::ASYNC && |
1487 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && | 1520 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && |
1488 next != Token::STATIC && next != Token::YIELD && | 1521 next != Token::STATIC && next != Token::YIELD && |
1489 next != Token::FUTURE_STRICT_RESERVED_WORD && | 1522 next != Token::FUTURE_STRICT_RESERVED_WORD && |
1490 next != Token::ESCAPED_KEYWORD && | 1523 next != Token::ESCAPED_KEYWORD && |
1491 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1524 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
1492 this->ReportUnexpectedToken(next); | 1525 this->ReportUnexpectedToken(next); |
1493 *ok = false; | 1526 *ok = false; |
1494 return Traits::EmptyIdentifier(); | 1527 return Traits::EmptyIdentifier(); |
1495 } | 1528 } |
1496 | 1529 |
1497 return this->GetSymbol(scanner()); | 1530 return this->GetSymbol(scanner()); |
1498 } | 1531 } |
1499 | 1532 |
1500 template <class Traits> | 1533 template <typename Impl> |
1501 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( | 1534 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( |
1502 bool* ok) { | 1535 bool* ok) { |
1503 int pos = peek_position(); | 1536 int pos = peek_position(); |
1504 if (!scanner()->ScanRegExpPattern()) { | 1537 if (!scanner()->ScanRegExpPattern()) { |
1505 Next(); | 1538 Next(); |
1506 ReportMessage(MessageTemplate::kUnterminatedRegExp); | 1539 ReportMessage(MessageTemplate::kUnterminatedRegExp); |
1507 *ok = false; | 1540 *ok = false; |
1508 return Traits::EmptyExpression(); | 1541 return Traits::EmptyExpression(); |
1509 } | 1542 } |
1510 | 1543 |
1511 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1544 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1512 | 1545 |
1513 IdentifierT js_pattern = this->GetNextSymbol(scanner()); | 1546 IdentifierT js_pattern = this->GetNextSymbol(scanner()); |
1514 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); | 1547 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); |
1515 if (flags.IsNothing()) { | 1548 if (flags.IsNothing()) { |
1516 Next(); | 1549 Next(); |
1517 ReportMessage(MessageTemplate::kMalformedRegExpFlags); | 1550 ReportMessage(MessageTemplate::kMalformedRegExpFlags); |
1518 *ok = false; | 1551 *ok = false; |
1519 return Traits::EmptyExpression(); | 1552 return Traits::EmptyExpression(); |
1520 } | 1553 } |
1521 int js_flags = flags.FromJust(); | 1554 int js_flags = flags.FromJust(); |
1522 Next(); | 1555 Next(); |
1523 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | 1556 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
1524 } | 1557 } |
1525 | 1558 |
1526 | 1559 template <typename Impl> |
1527 template <class Traits> | 1560 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( |
1528 typename ParserBase<Traits>::ExpressionT | 1561 ExpressionClassifier* classifier, bool* is_async, bool* ok) { |
1529 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, | |
1530 bool* is_async, bool* ok) { | |
1531 // PrimaryExpression :: | 1562 // PrimaryExpression :: |
1532 // 'this' | 1563 // 'this' |
1533 // 'null' | 1564 // 'null' |
1534 // 'true' | 1565 // 'true' |
1535 // 'false' | 1566 // 'false' |
1536 // Identifier | 1567 // Identifier |
1537 // Number | 1568 // Number |
1538 // String | 1569 // String |
1539 // ArrayLiteral | 1570 // ArrayLiteral |
1540 // ObjectLiteral | 1571 // ObjectLiteral |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 | 1728 |
1698 default: | 1729 default: |
1699 break; | 1730 break; |
1700 } | 1731 } |
1701 | 1732 |
1702 ReportUnexpectedToken(Next()); | 1733 ReportUnexpectedToken(Next()); |
1703 *ok = false; | 1734 *ok = false; |
1704 return this->EmptyExpression(); | 1735 return this->EmptyExpression(); |
1705 } | 1736 } |
1706 | 1737 |
1707 | 1738 template <typename Impl> |
1708 template <class Traits> | 1739 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
1709 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | |
1710 bool accept_IN, bool* ok) { | 1740 bool accept_IN, bool* ok) { |
1711 ExpressionClassifier classifier(this); | 1741 ExpressionClassifier classifier(this); |
1712 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1742 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
1713 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 1743 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
1714 return result; | 1744 return result; |
1715 } | 1745 } |
1716 | 1746 |
1717 template <class Traits> | 1747 template <typename Impl> |
1718 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1748 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
1719 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1749 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
1720 // Expression :: | 1750 // Expression :: |
1721 // AssignmentExpression | 1751 // AssignmentExpression |
1722 // Expression ',' AssignmentExpression | 1752 // Expression ',' AssignmentExpression |
1723 | 1753 |
1724 ExpressionT result; | 1754 ExpressionT result; |
1725 { | 1755 { |
1726 ExpressionClassifier binding_classifier(this); | 1756 ExpressionClassifier binding_classifier(this); |
1727 result = this->ParseAssignmentExpression(accept_IN, &binding_classifier, | 1757 result = this->ParseAssignmentExpression(accept_IN, &binding_classifier, |
1728 CHECK_OK); | 1758 CHECK_OK); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 is_simple_parameter_list && this->IsIdentifier(right); | 1802 is_simple_parameter_list && this->IsIdentifier(right); |
1773 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 1803 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
1774 } | 1804 } |
1775 if (!is_simple_parameter_list || seen_rest) { | 1805 if (!is_simple_parameter_list || seen_rest) { |
1776 classifier->RecordNonSimpleParameter(); | 1806 classifier->RecordNonSimpleParameter(); |
1777 } | 1807 } |
1778 | 1808 |
1779 return result; | 1809 return result; |
1780 } | 1810 } |
1781 | 1811 |
1782 | 1812 template <typename Impl> |
1783 template <class Traits> | 1813 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( |
1784 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | |
1785 ExpressionClassifier* classifier, bool* ok) { | 1814 ExpressionClassifier* classifier, bool* ok) { |
1786 // ArrayLiteral :: | 1815 // ArrayLiteral :: |
1787 // '[' Expression? (',' Expression?)* ']' | 1816 // '[' Expression? (',' Expression?)* ']' |
1788 | 1817 |
1789 int pos = peek_position(); | 1818 int pos = peek_position(); |
1790 typename Traits::Type::ExpressionList values = | 1819 typename Traits::Type::ExpressionList values = |
1791 this->NewExpressionList(4, zone_); | 1820 this->NewExpressionList(4, zone_); |
1792 int first_spread_index = -1; | 1821 int first_spread_index = -1; |
1793 Expect(Token::LBRACK, CHECK_OK); | 1822 Expect(Token::LBRACK, CHECK_OK); |
1794 while (peek() != Token::RBRACK) { | 1823 while (peek() != Token::RBRACK) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1849 // rewriting other things than spreads, this error message will have | 1878 // rewriting other things than spreads, this error message will have |
1850 // to change. Also, this error message will never appear while pre- | 1879 // to change. Also, this error message will never appear while pre- |
1851 // parsing (this is OK, as it is an implementation limitation). | 1880 // parsing (this is OK, as it is an implementation limitation). |
1852 ReportMessage(MessageTemplate::kTooManySpreads); | 1881 ReportMessage(MessageTemplate::kTooManySpreads); |
1853 return this->EmptyExpression(); | 1882 return this->EmptyExpression(); |
1854 } | 1883 } |
1855 } | 1884 } |
1856 return result; | 1885 return result; |
1857 } | 1886 } |
1858 | 1887 |
1859 template <class Traits> | 1888 template <class Impl> |
1860 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 1889 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( |
1861 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, | 1890 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name, |
1862 ExpressionClassifier* classifier, bool* ok) { | 1891 ExpressionClassifier* classifier, bool* ok) { |
1863 Token::Value token = peek(); | 1892 Token::Value token = peek(); |
1864 int pos = peek_position(); | 1893 int pos = peek_position(); |
1865 | 1894 |
1866 // For non computed property names we normalize the name a bit: | 1895 // For non computed property names we normalize the name a bit: |
1867 // | 1896 // |
1868 // "12" -> 12 | 1897 // "12" -> 12 |
1869 // 12.3 -> "12.3" | 1898 // 12.3 -> "12.3" |
1870 // 12.30 -> "12.3" | 1899 // 12.30 -> "12.3" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1906 scanner()->IsGetOrSet(is_get, is_set); | 1935 scanner()->IsGetOrSet(is_get, is_set); |
1907 break; | 1936 break; |
1908 } | 1937 } |
1909 | 1938 |
1910 uint32_t index; | 1939 uint32_t index; |
1911 return this->IsArrayIndex(*name, &index) | 1940 return this->IsArrayIndex(*name, &index) |
1912 ? factory()->NewNumberLiteral(index, pos) | 1941 ? factory()->NewNumberLiteral(index, pos) |
1913 : factory()->NewStringLiteral(*name, pos); | 1942 : factory()->NewStringLiteral(*name, pos); |
1914 } | 1943 } |
1915 | 1944 |
1916 template <class Traits> | 1945 template <typename Impl> |
1917 typename ParserBase<Traits>::ObjectLiteralPropertyT | 1946 typename ParserBase<Impl>::ObjectLiteralPropertyT |
1918 ParserBase<Traits>::ParsePropertyDefinition( | 1947 ParserBase<Impl>::ParsePropertyDefinition( |
1919 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1948 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
1920 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor, | 1949 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor, |
1921 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { | 1950 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { |
1922 DCHECK(!in_class || IsStaticMethod(method_kind) || | 1951 DCHECK(!in_class || IsStaticMethod(method_kind) || |
1923 has_seen_constructor != nullptr); | 1952 has_seen_constructor != nullptr); |
1924 bool is_get = false; | 1953 bool is_get = false; |
1925 bool is_set = false; | 1954 bool is_set = false; |
1926 bool is_generator = Check(Token::MUL); | 1955 bool is_generator = Check(Token::MUL); |
1927 bool is_async = false; | 1956 bool is_async = false; |
1928 const bool is_static = IsStaticMethod(method_kind); | 1957 const bool is_static = IsStaticMethod(method_kind); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2124 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, | 2153 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, |
2125 is_static, *is_computed_name); | 2154 is_static, *is_computed_name); |
2126 } | 2155 } |
2127 | 2156 |
2128 Token::Value next = Next(); | 2157 Token::Value next = Next(); |
2129 ReportUnexpectedToken(next); | 2158 ReportUnexpectedToken(next); |
2130 *ok = false; | 2159 *ok = false; |
2131 return this->EmptyObjectLiteralProperty(); | 2160 return this->EmptyObjectLiteralProperty(); |
2132 } | 2161 } |
2133 | 2162 |
2134 | 2163 template <typename Impl> |
2135 template <class Traits> | 2164 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
2136 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | |
2137 ExpressionClassifier* classifier, bool* ok) { | 2165 ExpressionClassifier* classifier, bool* ok) { |
2138 // ObjectLiteral :: | 2166 // ObjectLiteral :: |
2139 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2167 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2140 | 2168 |
2141 int pos = peek_position(); | 2169 int pos = peek_position(); |
2142 typename Traits::Type::PropertyList properties = | 2170 typename Traits::Type::PropertyList properties = |
2143 this->NewPropertyList(4, zone_); | 2171 this->NewPropertyList(4, zone_); |
2144 int number_of_boilerplate_properties = 0; | 2172 int number_of_boilerplate_properties = 0; |
2145 bool has_computed_names = false; | 2173 bool has_computed_names = false; |
2146 ObjectLiteralChecker checker(this); | 2174 ObjectLiteralChecker checker(this); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2181 | 2209 |
2182 // Computation of literal_index must happen before pre parse bailout. | 2210 // Computation of literal_index must happen before pre parse bailout. |
2183 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2211 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2184 | 2212 |
2185 return factory()->NewObjectLiteral(properties, | 2213 return factory()->NewObjectLiteral(properties, |
2186 literal_index, | 2214 literal_index, |
2187 number_of_boilerplate_properties, | 2215 number_of_boilerplate_properties, |
2188 pos); | 2216 pos); |
2189 } | 2217 } |
2190 | 2218 |
2191 template <class Traits> | 2219 template <typename Impl> |
2192 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2220 typename ParserBase<Impl>::Traits::Type::ExpressionList |
2193 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, | 2221 ParserBase<Impl>::ParseArguments(Scanner::Location* first_spread_arg_loc, |
2194 ExpressionClassifier* classifier, bool* ok) { | 2222 bool maybe_arrow, |
| 2223 ExpressionClassifier* classifier, bool* ok) { |
2195 // Arguments :: | 2224 // Arguments :: |
2196 // '(' (AssignmentExpression)*[','] ')' | 2225 // '(' (AssignmentExpression)*[','] ')' |
2197 | 2226 |
2198 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2227 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2199 typename Traits::Type::ExpressionList result = | 2228 typename Traits::Type::ExpressionList result = |
2200 this->NewExpressionList(4, zone_); | 2229 this->NewExpressionList(4, zone_); |
2201 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2230 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2202 bool done = (peek() == Token::RPAREN); | 2231 bool done = (peek() == Token::RPAREN); |
2203 bool was_unspread = false; | 2232 bool was_unspread = false; |
2204 int unspread_sequences_count = 0; | 2233 int unspread_sequences_count = 0; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2264 // parser. Ensure that the number of materialized literals matches between | 2293 // parser. Ensure that the number of materialized literals matches between |
2265 // the parser and preparser | 2294 // the parser and preparser |
2266 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2295 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
2267 } | 2296 } |
2268 } | 2297 } |
2269 | 2298 |
2270 return result; | 2299 return result; |
2271 } | 2300 } |
2272 | 2301 |
2273 // Precedence = 2 | 2302 // Precedence = 2 |
2274 template <class Traits> | 2303 template <typename Impl> |
2275 typename ParserBase<Traits>::ExpressionT | 2304 typename ParserBase<Impl>::ExpressionT |
2276 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 2305 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, |
2277 ExpressionClassifier* classifier, | 2306 ExpressionClassifier* classifier, |
2278 bool* ok) { | 2307 bool* ok) { |
2279 // AssignmentExpression :: | 2308 // AssignmentExpression :: |
2280 // ConditionalExpression | 2309 // ConditionalExpression |
2281 // ArrowFunction | 2310 // ArrowFunction |
2282 // YieldExpression | 2311 // YieldExpression |
2283 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2312 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2284 bool is_destructuring_assignment = false; | 2313 bool is_destructuring_assignment = false; |
2285 int lhs_beg_pos = peek_position(); | 2314 int lhs_beg_pos = peek_position(); |
2286 | 2315 |
2287 if (peek() == Token::YIELD && is_generator()) { | 2316 if (peek() == Token::YIELD && is_generator()) { |
2288 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2317 return this->ParseYieldExpression(accept_IN, classifier, ok); |
2289 } | 2318 } |
2290 | 2319 |
2291 FuncNameInferrer::State fni_state(fni_); | 2320 FuncNameInferrer::State fni_state(fni_); |
2292 ParserBase<Traits>::Checkpoint checkpoint(this); | 2321 Checkpoint checkpoint(this); |
2293 ExpressionClassifier arrow_formals_classifier(this, | 2322 ExpressionClassifier arrow_formals_classifier(this, |
2294 classifier->duplicate_finder()); | 2323 classifier->duplicate_finder()); |
2295 | 2324 |
2296 Scope::Snapshot scope_snapshot(scope()); | 2325 Scope::Snapshot scope_snapshot(scope()); |
2297 | 2326 |
2298 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && | 2327 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && |
2299 !scanner()->HasAnyLineTerminatorAfterNext() && | 2328 !scanner()->HasAnyLineTerminatorAfterNext() && |
2300 IsValidArrowFormalParametersStart(PeekAhead()); | 2329 IsValidArrowFormalParametersStart(PeekAhead()); |
2301 | 2330 |
2302 bool parenthesized_formals = peek() == Token::LPAREN; | 2331 bool parenthesized_formals = peek() == Token::LPAREN; |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2471 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); | 2500 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
2472 | 2501 |
2473 if (is_destructuring_assignment) { | 2502 if (is_destructuring_assignment) { |
2474 result = factory()->NewRewritableExpression(result); | 2503 result = factory()->NewRewritableExpression(result); |
2475 Traits::QueueDestructuringAssignmentForRewriting(result); | 2504 Traits::QueueDestructuringAssignmentForRewriting(result); |
2476 } | 2505 } |
2477 | 2506 |
2478 return result; | 2507 return result; |
2479 } | 2508 } |
2480 | 2509 |
2481 template <class Traits> | 2510 template <typename Impl> |
2482 typename ParserBase<Traits>::ExpressionT | 2511 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( |
2483 ParserBase<Traits>::ParseYieldExpression(bool accept_IN, | 2512 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
2484 ExpressionClassifier* classifier, | |
2485 bool* ok) { | |
2486 // YieldExpression :: | 2513 // YieldExpression :: |
2487 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2514 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
2488 int pos = peek_position(); | 2515 int pos = peek_position(); |
2489 classifier->RecordPatternError(scanner()->peek_location(), | 2516 classifier->RecordPatternError(scanner()->peek_location(), |
2490 MessageTemplate::kInvalidDestructuringTarget); | 2517 MessageTemplate::kInvalidDestructuringTarget); |
2491 classifier->RecordFormalParameterInitializerError( | 2518 classifier->RecordFormalParameterInitializerError( |
2492 scanner()->peek_location(), MessageTemplate::kYieldInParameter); | 2519 scanner()->peek_location(), MessageTemplate::kYieldInParameter); |
2493 Expect(Token::YIELD, CHECK_OK); | 2520 Expect(Token::YIELD, CHECK_OK); |
2494 ExpressionT generator_object = | 2521 ExpressionT generator_object = |
2495 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 2522 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
(...skipping 28 matching lines...) Expand all Loading... |
2524 } | 2551 } |
2525 | 2552 |
2526 expression = Traits::BuildIteratorResult(expression, false); | 2553 expression = Traits::BuildIteratorResult(expression, false); |
2527 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2554 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
2528 // TODO(verwaest): Come up with a better solution. | 2555 // TODO(verwaest): Come up with a better solution. |
2529 typename Traits::Type::YieldExpression yield = factory()->NewYield( | 2556 typename Traits::Type::YieldExpression yield = factory()->NewYield( |
2530 generator_object, expression, pos, Yield::kOnExceptionThrow); | 2557 generator_object, expression, pos, Yield::kOnExceptionThrow); |
2531 return yield; | 2558 return yield; |
2532 } | 2559 } |
2533 | 2560 |
2534 template <class Traits> | 2561 template <typename Impl> |
2535 typename ParserBase<Traits>::ExpressionT | 2562 typename ParserBase<Impl>::ExpressionT |
2536 ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier, | 2563 ParserBase<Impl>::ParseTailCallExpression(ExpressionClassifier* classifier, |
2537 bool* ok) { | 2564 bool* ok) { |
2538 // TailCallExpression:: | 2565 // TailCallExpression:: |
2539 // 'continue' MemberExpression Arguments | 2566 // 'continue' MemberExpression Arguments |
2540 // 'continue' CallExpression Arguments | 2567 // 'continue' CallExpression Arguments |
2541 // 'continue' MemberExpression TemplateLiteral | 2568 // 'continue' MemberExpression TemplateLiteral |
2542 // 'continue' CallExpression TemplateLiteral | 2569 // 'continue' CallExpression TemplateLiteral |
2543 Expect(Token::CONTINUE, CHECK_OK); | 2570 Expect(Token::CONTINUE, CHECK_OK); |
2544 int pos = position(); | 2571 int pos = position(); |
2545 int sub_expression_pos = peek_position(); | 2572 int sub_expression_pos = peek_position(); |
2546 ExpressionT expression = | 2573 ExpressionT expression = |
2547 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 2574 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2587 *ok = false; | 2614 *ok = false; |
2588 return Traits::EmptyExpression(); | 2615 return Traits::EmptyExpression(); |
2589 } | 2616 } |
2590 classifier->RecordTailCallExpressionError( | 2617 classifier->RecordTailCallExpressionError( |
2591 loc, MessageTemplate::kUnexpectedTailCall); | 2618 loc, MessageTemplate::kUnexpectedTailCall); |
2592 function_state_->AddExplicitTailCallExpression(expression, loc); | 2619 function_state_->AddExplicitTailCallExpression(expression, loc); |
2593 return expression; | 2620 return expression; |
2594 } | 2621 } |
2595 | 2622 |
2596 // Precedence = 3 | 2623 // Precedence = 3 |
2597 template <class Traits> | 2624 template <typename Impl> |
2598 typename ParserBase<Traits>::ExpressionT | 2625 typename ParserBase<Impl>::ExpressionT |
2599 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, | 2626 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, |
2600 ExpressionClassifier* classifier, | 2627 ExpressionClassifier* classifier, |
2601 bool* ok) { | 2628 bool* ok) { |
2602 // ConditionalExpression :: | 2629 // ConditionalExpression :: |
2603 // LogicalOrExpression | 2630 // LogicalOrExpression |
2604 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2631 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2605 | 2632 |
2606 int pos = peek_position(); | 2633 int pos = peek_position(); |
2607 // We start using the binary expression parser for prec >= 4 only! | 2634 // We start using the binary expression parser for prec >= 4 only! |
2608 ExpressionT expression = | 2635 ExpressionT expression = |
2609 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | 2636 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
2610 if (peek() != Token::CONDITIONAL) return expression; | 2637 if (peek() != Token::CONDITIONAL) return expression; |
2611 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2638 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2612 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2639 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2613 BindingPatternUnexpectedToken(classifier); | 2640 BindingPatternUnexpectedToken(classifier); |
2614 ArrowFormalParametersUnexpectedToken(classifier); | 2641 ArrowFormalParametersUnexpectedToken(classifier); |
2615 Consume(Token::CONDITIONAL); | 2642 Consume(Token::CONDITIONAL); |
2616 // In parsing the first assignment expression in conditional | 2643 // In parsing the first assignment expression in conditional |
2617 // expressions we always accept the 'in' keyword; see ECMA-262, | 2644 // expressions we always accept the 'in' keyword; see ECMA-262, |
2618 // section 11.12, page 58. | 2645 // section 11.12, page 58. |
2619 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 2646 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
2620 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2647 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2621 Expect(Token::COLON, CHECK_OK); | 2648 Expect(Token::COLON, CHECK_OK); |
2622 ExpressionT right = | 2649 ExpressionT right = |
2623 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2650 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2624 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2651 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2625 return factory()->NewConditional(expression, left, right, pos); | 2652 return factory()->NewConditional(expression, left, right, pos); |
2626 } | 2653 } |
2627 | 2654 |
2628 | 2655 |
2629 // Precedence >= 4 | 2656 // Precedence >= 4 |
2630 template <class Traits> | 2657 template <typename Impl> |
2631 typename ParserBase<Traits>::ExpressionT | 2658 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( |
2632 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, | 2659 int prec, bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
2633 ExpressionClassifier* classifier, | |
2634 bool* ok) { | |
2635 DCHECK(prec >= 4); | 2660 DCHECK(prec >= 4); |
2636 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 2661 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
2637 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2662 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2638 // prec1 >= 4 | 2663 // prec1 >= 4 |
2639 while (Precedence(peek(), accept_IN) == prec1) { | 2664 while (Precedence(peek(), accept_IN) == prec1) { |
2640 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2665 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2641 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2666 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2642 BindingPatternUnexpectedToken(classifier); | 2667 BindingPatternUnexpectedToken(classifier); |
2643 ArrowFormalParametersUnexpectedToken(classifier); | 2668 ArrowFormalParametersUnexpectedToken(classifier); |
2644 Token::Value op = Next(); | 2669 Token::Value op = Next(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2678 x = Traits::RewriteExponentiation(x, y, pos); | 2703 x = Traits::RewriteExponentiation(x, y, pos); |
2679 } else { | 2704 } else { |
2680 // We have a "normal" binary operation. | 2705 // We have a "normal" binary operation. |
2681 x = factory()->NewBinaryOperation(op, x, y, pos); | 2706 x = factory()->NewBinaryOperation(op, x, y, pos); |
2682 } | 2707 } |
2683 } | 2708 } |
2684 } | 2709 } |
2685 return x; | 2710 return x; |
2686 } | 2711 } |
2687 | 2712 |
2688 | 2713 template <typename Impl> |
2689 template <class Traits> | 2714 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( |
2690 typename ParserBase<Traits>::ExpressionT | 2715 ExpressionClassifier* classifier, bool* ok) { |
2691 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, | |
2692 bool* ok) { | |
2693 // UnaryExpression :: | 2716 // UnaryExpression :: |
2694 // PostfixExpression | 2717 // PostfixExpression |
2695 // 'delete' UnaryExpression | 2718 // 'delete' UnaryExpression |
2696 // 'void' UnaryExpression | 2719 // 'void' UnaryExpression |
2697 // 'typeof' UnaryExpression | 2720 // 'typeof' UnaryExpression |
2698 // '++' UnaryExpression | 2721 // '++' UnaryExpression |
2699 // '--' UnaryExpression | 2722 // '--' UnaryExpression |
2700 // '+' UnaryExpression | 2723 // '+' UnaryExpression |
2701 // '-' UnaryExpression | 2724 // '-' UnaryExpression |
2702 // '~' UnaryExpression | 2725 // '~' UnaryExpression |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2758 Consume(Token::AWAIT); | 2781 Consume(Token::AWAIT); |
2759 | 2782 |
2760 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); | 2783 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); |
2761 | 2784 |
2762 return Traits::RewriteAwaitExpression(value, await_pos); | 2785 return Traits::RewriteAwaitExpression(value, await_pos); |
2763 } else { | 2786 } else { |
2764 return this->ParsePostfixExpression(classifier, ok); | 2787 return this->ParsePostfixExpression(classifier, ok); |
2765 } | 2788 } |
2766 } | 2789 } |
2767 | 2790 |
2768 | 2791 template <typename Impl> |
2769 template <class Traits> | 2792 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( |
2770 typename ParserBase<Traits>::ExpressionT | 2793 ExpressionClassifier* classifier, bool* ok) { |
2771 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | |
2772 bool* ok) { | |
2773 // PostfixExpression :: | 2794 // PostfixExpression :: |
2774 // LeftHandSideExpression ('++' | '--')? | 2795 // LeftHandSideExpression ('++' | '--')? |
2775 | 2796 |
2776 int lhs_beg_pos = peek_position(); | 2797 int lhs_beg_pos = peek_position(); |
2777 ExpressionT expression = | 2798 ExpressionT expression = |
2778 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 2799 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
2779 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2800 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2780 Token::IsCountOp(peek())) { | 2801 Token::IsCountOp(peek())) { |
2781 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2802 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2782 BindingPatternUnexpectedToken(classifier); | 2803 BindingPatternUnexpectedToken(classifier); |
2783 ArrowFormalParametersUnexpectedToken(classifier); | 2804 ArrowFormalParametersUnexpectedToken(classifier); |
2784 | 2805 |
2785 expression = this->CheckAndRewriteReferenceExpression( | 2806 expression = this->CheckAndRewriteReferenceExpression( |
2786 expression, lhs_beg_pos, scanner()->location().end_pos, | 2807 expression, lhs_beg_pos, scanner()->location().end_pos, |
2787 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); | 2808 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
2788 expression = this->MarkExpressionAsAssigned(expression); | 2809 expression = this->MarkExpressionAsAssigned(expression); |
2789 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2810 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2790 | 2811 |
2791 Token::Value next = Next(); | 2812 Token::Value next = Next(); |
2792 expression = | 2813 expression = |
2793 factory()->NewCountOperation(next, | 2814 factory()->NewCountOperation(next, |
2794 false /* postfix */, | 2815 false /* postfix */, |
2795 expression, | 2816 expression, |
2796 position()); | 2817 position()); |
2797 } | 2818 } |
2798 return expression; | 2819 return expression; |
2799 } | 2820 } |
2800 | 2821 |
2801 template <class Traits> | 2822 template <typename Impl> |
2802 typename ParserBase<Traits>::ExpressionT | 2823 typename ParserBase<Impl>::ExpressionT |
2803 ParserBase<Traits>::ParseLeftHandSideExpression( | 2824 ParserBase<Impl>::ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
2804 ExpressionClassifier* classifier, bool* ok) { | 2825 bool* ok) { |
2805 // LeftHandSideExpression :: | 2826 // LeftHandSideExpression :: |
2806 // (NewExpression | MemberExpression) ... | 2827 // (NewExpression | MemberExpression) ... |
2807 | 2828 |
2808 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { | 2829 if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) { |
2809 return this->ParseTailCallExpression(classifier, ok); | 2830 return this->ParseTailCallExpression(classifier, ok); |
2810 } | 2831 } |
2811 | 2832 |
2812 bool is_async = false; | 2833 bool is_async = false; |
2813 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( | 2834 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( |
2814 classifier, &is_async, CHECK_OK); | 2835 classifier, &is_async, CHECK_OK); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2939 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2960 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
2940 break; | 2961 break; |
2941 } | 2962 } |
2942 | 2963 |
2943 default: | 2964 default: |
2944 return result; | 2965 return result; |
2945 } | 2966 } |
2946 } | 2967 } |
2947 } | 2968 } |
2948 | 2969 |
2949 template <class Traits> | 2970 template <typename Impl> |
2950 typename ParserBase<Traits>::ExpressionT | 2971 typename ParserBase<Impl>::ExpressionT |
2951 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( | 2972 ParserBase<Impl>::ParseMemberWithNewPrefixesExpression( |
2952 ExpressionClassifier* classifier, bool* is_async, bool* ok) { | 2973 ExpressionClassifier* classifier, bool* is_async, bool* ok) { |
2953 // NewExpression :: | 2974 // NewExpression :: |
2954 // ('new')+ MemberExpression | 2975 // ('new')+ MemberExpression |
2955 // | 2976 // |
2956 // NewTarget :: | 2977 // NewTarget :: |
2957 // 'new' '.' 'target' | 2978 // 'new' '.' 'target' |
2958 | 2979 |
2959 // The grammar for new expressions is pretty warped. We can have several 'new' | 2980 // The grammar for new expressions is pretty warped. We can have several 'new' |
2960 // keywords following each other, and then a MemberExpression. When we see '(' | 2981 // keywords following each other, and then a MemberExpression. When we see '(' |
2961 // after the MemberExpression, it's associated with the rightmost unassociated | 2982 // after the MemberExpression, it's associated with the rightmost unassociated |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3004 return result; | 3025 return result; |
3005 } | 3026 } |
3006 // NewExpression without arguments. | 3027 // NewExpression without arguments. |
3007 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 3028 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
3008 new_pos); | 3029 new_pos); |
3009 } | 3030 } |
3010 // No 'new' or 'super' keyword. | 3031 // No 'new' or 'super' keyword. |
3011 return this->ParseMemberExpression(classifier, is_async, ok); | 3032 return this->ParseMemberExpression(classifier, is_async, ok); |
3012 } | 3033 } |
3013 | 3034 |
3014 template <class Traits> | 3035 template <typename Impl> |
3015 typename ParserBase<Traits>::ExpressionT | 3036 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( |
3016 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, | 3037 ExpressionClassifier* classifier, bool* is_async, bool* ok) { |
3017 bool* is_async, bool* ok) { | |
3018 // MemberExpression :: | 3038 // MemberExpression :: |
3019 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 3039 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
3020 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3040 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
3021 | 3041 |
3022 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3042 // The '[' Expression ']' and '.' Identifier parts are parsed by |
3023 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3043 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
3024 // caller. | 3044 // caller. |
3025 | 3045 |
3026 // Parse the initial primary or function expression. | 3046 // Parse the initial primary or function expression. |
3027 ExpressionT result; | 3047 ExpressionT result; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3073 result = ParseSuperExpression(is_new, CHECK_OK); | 3093 result = ParseSuperExpression(is_new, CHECK_OK); |
3074 } else { | 3094 } else { |
3075 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); | 3095 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); |
3076 } | 3096 } |
3077 | 3097 |
3078 result = | 3098 result = |
3079 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK); | 3099 ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK); |
3080 return result; | 3100 return result; |
3081 } | 3101 } |
3082 | 3102 |
3083 template <class Traits> | 3103 template <typename Impl> |
3084 typename ParserBase<Traits>::ExpressionT | 3104 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression( |
3085 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { | 3105 bool is_new, bool* ok) { |
3086 Expect(Token::SUPER, CHECK_OK); | 3106 Expect(Token::SUPER, CHECK_OK); |
3087 int pos = position(); | 3107 int pos = position(); |
3088 | 3108 |
3089 DeclarationScope* scope = GetReceiverScope(); | 3109 DeclarationScope* scope = GetReceiverScope(); |
3090 FunctionKind kind = scope->function_kind(); | 3110 FunctionKind kind = scope->function_kind(); |
3091 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3111 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
3092 IsClassConstructor(kind)) { | 3112 IsClassConstructor(kind)) { |
3093 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3113 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
3094 scope->RecordSuperPropertyUsage(); | 3114 scope->RecordSuperPropertyUsage(); |
3095 return this->NewSuperPropertyReference(factory(), pos); | 3115 return this->NewSuperPropertyReference(factory(), pos); |
3096 } | 3116 } |
3097 // new super() is never allowed. | 3117 // new super() is never allowed. |
3098 // super() is only allowed in derived constructor | 3118 // super() is only allowed in derived constructor |
3099 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3119 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
3100 // TODO(rossberg): This might not be the correct FunctionState for the | 3120 // TODO(rossberg): This might not be the correct FunctionState for the |
3101 // method here. | 3121 // method here. |
3102 return this->NewSuperCallReference(factory(), pos); | 3122 return this->NewSuperCallReference(factory(), pos); |
3103 } | 3123 } |
3104 } | 3124 } |
3105 | 3125 |
3106 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); | 3126 ReportMessageAt(scanner()->location(), MessageTemplate::kUnexpectedSuper); |
3107 *ok = false; | 3127 *ok = false; |
3108 return this->EmptyExpression(); | 3128 return this->EmptyExpression(); |
3109 } | 3129 } |
3110 | 3130 |
3111 template <class Traits> | 3131 template <typename Impl> |
3112 void ParserBase<Traits>::ExpectMetaProperty(Vector<const char> property_name, | 3132 void ParserBase<Impl>::ExpectMetaProperty(Vector<const char> property_name, |
3113 const char* full_name, int pos, | 3133 const char* full_name, int pos, |
3114 bool* ok) { | 3134 bool* ok) { |
3115 Consume(Token::PERIOD); | 3135 Consume(Token::PERIOD); |
3116 ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void)); | 3136 ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void)); |
3117 if (scanner()->literal_contains_escapes()) { | 3137 if (scanner()->literal_contains_escapes()) { |
3118 Traits::ReportMessageAt( | 3138 Traits::ReportMessageAt( |
3119 Scanner::Location(pos, scanner()->location().end_pos), | 3139 Scanner::Location(pos, scanner()->location().end_pos), |
3120 MessageTemplate::kInvalidEscapedMetaProperty, full_name); | 3140 MessageTemplate::kInvalidEscapedMetaProperty, full_name); |
3121 *ok = false; | 3141 *ok = false; |
3122 } | 3142 } |
3123 } | 3143 } |
3124 | 3144 |
3125 template <class Traits> | 3145 template <typename Impl> |
3126 typename ParserBase<Traits>::ExpressionT | 3146 typename ParserBase<Impl>::ExpressionT |
3127 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) { | 3147 ParserBase<Impl>::ParseNewTargetExpression(bool* ok) { |
3128 int pos = position(); | 3148 int pos = position(); |
3129 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); | 3149 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); |
3130 | 3150 |
3131 if (!GetReceiverScope()->is_function_scope()) { | 3151 if (!GetReceiverScope()->is_function_scope()) { |
3132 ReportMessageAt(scanner()->location(), | 3152 ReportMessageAt(scanner()->location(), |
3133 MessageTemplate::kUnexpectedNewTarget); | 3153 MessageTemplate::kUnexpectedNewTarget); |
3134 *ok = false; | 3154 *ok = false; |
3135 return this->EmptyExpression(); | 3155 return this->EmptyExpression(); |
3136 } | 3156 } |
3137 | 3157 |
3138 return this->NewTargetExpression(pos); | 3158 return this->NewTargetExpression(pos); |
3139 } | 3159 } |
3140 | 3160 |
3141 template <class Traits> | 3161 template <typename Impl> |
3142 typename ParserBase<Traits>::ExpressionT | 3162 typename ParserBase<Impl>::ExpressionT |
3143 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3163 ParserBase<Impl>::ParseMemberExpressionContinuation( |
3144 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | 3164 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
3145 bool* ok) { | 3165 bool* ok) { |
3146 // Parses this part of MemberExpression: | 3166 // Parses this part of MemberExpression: |
3147 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3167 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
3148 while (true) { | 3168 while (true) { |
3149 switch (peek()) { | 3169 switch (peek()) { |
3150 case Token::LBRACK: { | 3170 case Token::LBRACK: { |
3151 *is_async = false; | 3171 *is_async = false; |
3152 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3172 Traits::RewriteNonPattern(classifier, CHECK_OK); |
3153 BindingPatternUnexpectedToken(classifier); | 3173 BindingPatternUnexpectedToken(classifier); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3207 return this->EmptyExpression(); | 3227 return this->EmptyExpression(); |
3208 } | 3228 } |
3209 default: | 3229 default: |
3210 return expression; | 3230 return expression; |
3211 } | 3231 } |
3212 } | 3232 } |
3213 DCHECK(false); | 3233 DCHECK(false); |
3214 return this->EmptyExpression(); | 3234 return this->EmptyExpression(); |
3215 } | 3235 } |
3216 | 3236 |
3217 | 3237 template <typename Impl> |
3218 template <class Traits> | 3238 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, |
3219 void ParserBase<Traits>::ParseFormalParameter( | 3239 ExpressionClassifier* classifier, |
3220 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { | 3240 bool* ok) { |
3221 // FormalParameter[Yield,GeneratorParameter] : | 3241 // FormalParameter[Yield,GeneratorParameter] : |
3222 // BindingElement[?Yield, ?GeneratorParameter] | 3242 // BindingElement[?Yield, ?GeneratorParameter] |
3223 bool is_rest = parameters->has_rest; | 3243 bool is_rest = parameters->has_rest; |
3224 | 3244 |
3225 ExpressionT pattern = | 3245 ExpressionT pattern = |
3226 ParsePrimaryExpression(classifier, CHECK_OK_CUSTOM(Void)); | 3246 ParsePrimaryExpression(classifier, CHECK_OK_CUSTOM(Void)); |
3227 ValidateBindingPattern(classifier, CHECK_OK_CUSTOM(Void)); | 3247 ValidateBindingPattern(classifier, CHECK_OK_CUSTOM(Void)); |
3228 | 3248 |
3229 if (!Traits::IsIdentifier(pattern)) { | 3249 if (!Traits::IsIdentifier(pattern)) { |
3230 parameters->is_simple = false; | 3250 parameters->is_simple = false; |
(...skipping 12 matching lines...) Expand all Loading... |
3243 init_classifier.Discard(); | 3263 init_classifier.Discard(); |
3244 classifier->RecordNonSimpleParameter(); | 3264 classifier->RecordNonSimpleParameter(); |
3245 | 3265 |
3246 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); | 3266 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); |
3247 } | 3267 } |
3248 | 3268 |
3249 Traits::AddFormalParameter(parameters, pattern, initializer, | 3269 Traits::AddFormalParameter(parameters, pattern, initializer, |
3250 scanner()->location().end_pos, is_rest); | 3270 scanner()->location().end_pos, is_rest); |
3251 } | 3271 } |
3252 | 3272 |
3253 | 3273 template <typename Impl> |
3254 template <class Traits> | 3274 void ParserBase<Impl>::ParseFormalParameterList( |
3255 void ParserBase<Traits>::ParseFormalParameterList( | |
3256 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { | 3275 FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) { |
3257 // FormalParameters[Yield] : | 3276 // FormalParameters[Yield] : |
3258 // [empty] | 3277 // [empty] |
3259 // FunctionRestParameter[?Yield] | 3278 // FunctionRestParameter[?Yield] |
3260 // FormalParameterList[?Yield] | 3279 // FormalParameterList[?Yield] |
3261 // FormalParameterList[?Yield] , | 3280 // FormalParameterList[?Yield] , |
3262 // FormalParameterList[?Yield] , FunctionRestParameter[?Yield] | 3281 // FormalParameterList[?Yield] , FunctionRestParameter[?Yield] |
3263 // | 3282 // |
3264 // FormalParameterList[Yield] : | 3283 // FormalParameterList[Yield] : |
3265 // FormalParameter[?Yield] | 3284 // FormalParameter[?Yield] |
(...skipping 29 matching lines...) Expand all Loading... |
3295 } | 3314 } |
3296 } | 3315 } |
3297 } | 3316 } |
3298 | 3317 |
3299 for (int i = 0; i < parameters->Arity(); ++i) { | 3318 for (int i = 0; i < parameters->Arity(); ++i) { |
3300 auto parameter = parameters->at(i); | 3319 auto parameter = parameters->at(i); |
3301 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); | 3320 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); |
3302 } | 3321 } |
3303 } | 3322 } |
3304 | 3323 |
3305 template <class Traits> | 3324 template <typename Impl> |
3306 void ParserBase<Traits>::CheckArityRestrictions(int param_count, | 3325 void ParserBase<Impl>::CheckArityRestrictions(int param_count, |
3307 FunctionKind function_kind, | 3326 FunctionKind function_kind, |
3308 bool has_rest, | 3327 bool has_rest, |
3309 int formals_start_pos, | 3328 int formals_start_pos, |
3310 int formals_end_pos, bool* ok) { | 3329 int formals_end_pos, bool* ok) { |
3311 if (IsGetterFunction(function_kind)) { | 3330 if (IsGetterFunction(function_kind)) { |
3312 if (param_count != 0) { | 3331 if (param_count != 0) { |
3313 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3332 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
3314 MessageTemplate::kBadGetterArity); | 3333 MessageTemplate::kBadGetterArity); |
3315 *ok = false; | 3334 *ok = false; |
3316 } | 3335 } |
3317 } else if (IsSetterFunction(function_kind)) { | 3336 } else if (IsSetterFunction(function_kind)) { |
3318 if (param_count != 1) { | 3337 if (param_count != 1) { |
3319 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3338 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
3320 MessageTemplate::kBadSetterArity); | 3339 MessageTemplate::kBadSetterArity); |
3321 *ok = false; | 3340 *ok = false; |
3322 } | 3341 } |
3323 if (has_rest) { | 3342 if (has_rest) { |
3324 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), | 3343 ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos), |
3325 MessageTemplate::kBadSetterRestParameter); | 3344 MessageTemplate::kBadSetterRestParameter); |
3326 *ok = false; | 3345 *ok = false; |
3327 } | 3346 } |
3328 } | 3347 } |
3329 } | 3348 } |
3330 | 3349 |
3331 | 3350 template <typename Impl> |
3332 template <class Traits> | 3351 bool ParserBase<Impl>::IsNextLetKeyword() { |
3333 bool ParserBase<Traits>::IsNextLetKeyword() { | |
3334 DCHECK(peek() == Token::LET); | 3352 DCHECK(peek() == Token::LET); |
3335 Token::Value next_next = PeekAhead(); | 3353 Token::Value next_next = PeekAhead(); |
3336 switch (next_next) { | 3354 switch (next_next) { |
3337 case Token::LBRACE: | 3355 case Token::LBRACE: |
3338 case Token::LBRACK: | 3356 case Token::LBRACK: |
3339 case Token::IDENTIFIER: | 3357 case Token::IDENTIFIER: |
3340 case Token::STATIC: | 3358 case Token::STATIC: |
3341 case Token::LET: // `let let;` is disallowed by static semantics, but the | 3359 case Token::LET: // `let let;` is disallowed by static semantics, but the |
3342 // token must be first interpreted as a keyword in order | 3360 // token must be first interpreted as a keyword in order |
3343 // for those semantics to apply. This ensures that ASI is | 3361 // for those semantics to apply. This ensures that ASI is |
3344 // not honored when a LineTerminator separates the | 3362 // not honored when a LineTerminator separates the |
3345 // tokens. | 3363 // tokens. |
3346 case Token::YIELD: | 3364 case Token::YIELD: |
3347 case Token::AWAIT: | 3365 case Token::AWAIT: |
3348 case Token::ASYNC: | 3366 case Token::ASYNC: |
3349 return true; | 3367 return true; |
3350 case Token::FUTURE_STRICT_RESERVED_WORD: | 3368 case Token::FUTURE_STRICT_RESERVED_WORD: |
3351 return is_sloppy(language_mode()); | 3369 return is_sloppy(language_mode()); |
3352 default: | 3370 default: |
3353 return false; | 3371 return false; |
3354 } | 3372 } |
3355 } | 3373 } |
3356 | 3374 |
3357 template <class Traits> | 3375 template <typename Impl> |
3358 bool ParserBase<Traits>::IsTrivialExpression() { | 3376 bool ParserBase<Impl>::IsTrivialExpression() { |
3359 Token::Value peek_token = peek(); | 3377 Token::Value peek_token = peek(); |
3360 if (peek_token == Token::SMI || peek_token == Token::NUMBER || | 3378 if (peek_token == Token::SMI || peek_token == Token::NUMBER || |
3361 peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL || | 3379 peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL || |
3362 peek_token == Token::FALSE_LITERAL || peek_token == Token::STRING || | 3380 peek_token == Token::FALSE_LITERAL || peek_token == Token::STRING || |
3363 peek_token == Token::IDENTIFIER || peek_token == Token::THIS) { | 3381 peek_token == Token::IDENTIFIER || peek_token == Token::THIS) { |
3364 // PeekAhead() is expensive & may not always be called, so we only call it | 3382 // PeekAhead() is expensive & may not always be called, so we only call it |
3365 // after checking peek(). | 3383 // after checking peek(). |
3366 Token::Value peek_ahead = PeekAhead(); | 3384 Token::Value peek_ahead = PeekAhead(); |
3367 if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN || | 3385 if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN || |
3368 peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) { | 3386 peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) { |
3369 return true; | 3387 return true; |
3370 } | 3388 } |
3371 } | 3389 } |
3372 return false; | 3390 return false; |
3373 } | 3391 } |
3374 | 3392 |
3375 template <class Traits> | 3393 template <typename Impl> |
3376 typename ParserBase<Traits>::ExpressionT | 3394 typename ParserBase<Impl>::ExpressionT |
3377 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3395 ParserBase<Impl>::ParseArrowFunctionLiteral( |
3378 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, | 3396 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, |
3379 const ExpressionClassifier& formals_classifier, bool* ok) { | 3397 const ExpressionClassifier& formals_classifier, bool* ok) { |
3380 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3398 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3381 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3399 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3382 // `=> ...` is never a valid expression, so report as syntax error. | 3400 // `=> ...` is never a valid expression, so report as syntax error. |
3383 // If next token is not `=>`, it's a syntax error anyways. | 3401 // If next token is not `=>`, it's a syntax error anyways. |
3384 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3402 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3385 *ok = false; | 3403 *ok = false; |
3386 return this->EmptyExpression(); | 3404 return this->EmptyExpression(); |
3387 } | 3405 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3484 formal_parameters.scope->start_position()); | 3502 formal_parameters.scope->start_position()); |
3485 | 3503 |
3486 function_literal->set_function_token_position( | 3504 function_literal->set_function_token_position( |
3487 formal_parameters.scope->start_position()); | 3505 formal_parameters.scope->start_position()); |
3488 | 3506 |
3489 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3507 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3490 | 3508 |
3491 return function_literal; | 3509 return function_literal; |
3492 } | 3510 } |
3493 | 3511 |
3494 | 3512 template <typename Impl> |
3495 template <typename Traits> | 3513 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( |
3496 typename ParserBase<Traits>::ExpressionT | 3514 ExpressionT tag, int start, ExpressionClassifier* classifier, bool* ok) { |
3497 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, | |
3498 ExpressionClassifier* classifier, | |
3499 bool* ok) { | |
3500 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 3515 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
3501 // text followed by a substitution expression), finalized by a single | 3516 // text followed by a substitution expression), finalized by a single |
3502 // TEMPLATE_TAIL. | 3517 // TEMPLATE_TAIL. |
3503 // | 3518 // |
3504 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 3519 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
3505 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or | 3520 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or |
3506 // NoSubstitutionTemplate. | 3521 // NoSubstitutionTemplate. |
3507 // | 3522 // |
3508 // When parsing a TemplateLiteral, we must have scanned either an initial | 3523 // When parsing a TemplateLiteral, we must have scanned either an initial |
3509 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. | 3524 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3581 | 3596 |
3582 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); | 3597 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); |
3583 } while (next == Token::TEMPLATE_SPAN); | 3598 } while (next == Token::TEMPLATE_SPAN); |
3584 | 3599 |
3585 DCHECK_EQ(next, Token::TEMPLATE_TAIL); | 3600 DCHECK_EQ(next, Token::TEMPLATE_TAIL); |
3586 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3601 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
3587 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 3602 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
3588 return Traits::CloseTemplateLiteral(&ts, start, tag); | 3603 return Traits::CloseTemplateLiteral(&ts, start, tag); |
3589 } | 3604 } |
3590 | 3605 |
3591 | 3606 template <typename Impl> |
3592 template <typename Traits> | 3607 typename ParserBase<Impl>::ExpressionT |
3593 typename ParserBase<Traits>::ExpressionT | 3608 ParserBase<Impl>::CheckAndRewriteReferenceExpression( |
3594 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | |
3595 ExpressionT expression, int beg_pos, int end_pos, | 3609 ExpressionT expression, int beg_pos, int end_pos, |
3596 MessageTemplate::Template message, bool* ok) { | 3610 MessageTemplate::Template message, bool* ok) { |
3597 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, | 3611 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, |
3598 message, kReferenceError, ok); | 3612 message, kReferenceError, ok); |
3599 } | 3613 } |
3600 | 3614 |
3601 | 3615 template <typename Impl> |
3602 template <typename Traits> | 3616 typename ParserBase<Impl>::ExpressionT |
3603 typename ParserBase<Traits>::ExpressionT | 3617 ParserBase<Impl>::CheckAndRewriteReferenceExpression( |
3604 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | |
3605 ExpressionT expression, int beg_pos, int end_pos, | 3618 ExpressionT expression, int beg_pos, int end_pos, |
3606 MessageTemplate::Template message, ParseErrorType type, bool* ok) { | 3619 MessageTemplate::Template message, ParseErrorType type, bool* ok) { |
3607 if (this->IsIdentifier(expression) && is_strict(language_mode()) && | 3620 if (this->IsIdentifier(expression) && is_strict(language_mode()) && |
3608 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3621 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
3609 ReportMessageAt(Scanner::Location(beg_pos, end_pos), | 3622 ReportMessageAt(Scanner::Location(beg_pos, end_pos), |
3610 MessageTemplate::kStrictEvalArguments, kSyntaxError); | 3623 MessageTemplate::kStrictEvalArguments, kSyntaxError); |
3611 *ok = false; | 3624 *ok = false; |
3612 return this->EmptyExpression(); | 3625 return this->EmptyExpression(); |
3613 } | 3626 } |
3614 if (expression->IsValidReferenceExpression()) { | 3627 if (expression->IsValidReferenceExpression()) { |
3615 return expression; | 3628 return expression; |
3616 } | 3629 } |
3617 if (expression->IsCall()) { | 3630 if (expression->IsCall()) { |
3618 // If it is a call, make it a runtime error for legacy web compatibility. | 3631 // If it is a call, make it a runtime error for legacy web compatibility. |
3619 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3632 // Rewrite `expr' to `expr[throw ReferenceError]'. |
3620 ExpressionT error = this->NewThrowReferenceError(message, beg_pos); | 3633 ExpressionT error = this->NewThrowReferenceError(message, beg_pos); |
3621 return factory()->NewProperty(expression, error, beg_pos); | 3634 return factory()->NewProperty(expression, error, beg_pos); |
3622 } | 3635 } |
3623 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type); | 3636 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type); |
3624 *ok = false; | 3637 *ok = false; |
3625 return this->EmptyExpression(); | 3638 return this->EmptyExpression(); |
3626 } | 3639 } |
3627 | 3640 |
3628 | 3641 template <typename Impl> |
3629 template <typename Traits> | 3642 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) { |
3630 bool ParserBase<Traits>::IsValidReferenceExpression(ExpressionT expression) { | |
3631 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); | 3643 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); |
3632 } | 3644 } |
3633 | 3645 |
3634 | 3646 template <typename Impl> |
3635 template <typename Traits> | 3647 void ParserBase<Impl>::CheckDestructuringElement( |
3636 void ParserBase<Traits>::CheckDestructuringElement( | |
3637 ExpressionT expression, ExpressionClassifier* classifier, int begin, | 3648 ExpressionT expression, ExpressionClassifier* classifier, int begin, |
3638 int end) { | 3649 int end) { |
3639 if (!IsValidPattern(expression) && !expression->IsAssignment() && | 3650 if (!IsValidPattern(expression) && !expression->IsAssignment() && |
3640 !IsValidReferenceExpression(expression)) { | 3651 !IsValidReferenceExpression(expression)) { |
3641 classifier->RecordAssignmentPatternError( | 3652 classifier->RecordAssignmentPatternError( |
3642 Scanner::Location(begin, end), | 3653 Scanner::Location(begin, end), |
3643 MessageTemplate::kInvalidDestructuringTarget); | 3654 MessageTemplate::kInvalidDestructuringTarget); |
3644 } | 3655 } |
3645 } | 3656 } |
3646 | 3657 |
3647 | 3658 |
3648 #undef CHECK_OK | 3659 #undef CHECK_OK |
3649 #undef CHECK_OK_CUSTOM | 3660 #undef CHECK_OK_CUSTOM |
3650 | 3661 |
3651 template <typename Traits> | 3662 template <typename Impl> |
3652 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 3663 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( |
3653 Token::Value property, PropertyKind type, MethodKind method_type, | 3664 Token::Value property, PropertyKind type, MethodKind method_type, |
3654 ExpressionClassifier* classifier, bool* ok) { | 3665 ExpressionClassifier* classifier, bool* ok) { |
3655 DCHECK(!IsStaticMethod(method_type)); | 3666 DCHECK(!IsStaticMethod(method_type)); |
3656 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty); | 3667 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty); |
3657 | 3668 |
3658 if (property == Token::SMI || property == Token::NUMBER) return; | 3669 if (property == Token::SMI || property == Token::NUMBER) return; |
3659 | 3670 |
3660 if (type == kValueProperty && IsProto()) { | 3671 if (type == kValueProperty && IsProto()) { |
3661 if (has_seen_proto_) { | 3672 if (has_seen_proto_) { |
3662 classifier->RecordObjectLiteralError( | 3673 classifier->RecordObjectLiteralError( |
3663 this->scanner()->location(), MessageTemplate::kDuplicateProto); | 3674 this->scanner()->location(), MessageTemplate::kDuplicateProto); |
3664 return; | 3675 return; |
3665 } | 3676 } |
3666 has_seen_proto_ = true; | 3677 has_seen_proto_ = true; |
3667 } | 3678 } |
3668 } | 3679 } |
3669 | 3680 |
3670 template <typename Traits> | 3681 template <typename Impl> |
3671 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( | 3682 void ParserBase<Impl>::ClassLiteralChecker::CheckProperty( |
3672 Token::Value property, PropertyKind type, MethodKind method_type, | 3683 Token::Value property, PropertyKind type, MethodKind method_type, |
3673 ExpressionClassifier* classifier, bool* ok) { | 3684 ExpressionClassifier* classifier, bool* ok) { |
3674 DCHECK(type == kMethodProperty || type == kAccessorProperty); | 3685 DCHECK(type == kMethodProperty || type == kAccessorProperty); |
3675 | 3686 |
3676 if (property == Token::SMI || property == Token::NUMBER) return; | 3687 if (property == Token::SMI || property == Token::NUMBER) return; |
3677 | 3688 |
3678 if (IsStaticMethod(method_type)) { | 3689 if (IsStaticMethod(method_type)) { |
3679 if (IsPrototype()) { | 3690 if (IsPrototype()) { |
3680 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); | 3691 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); |
3681 *ok = false; | 3692 *ok = false; |
(...skipping 19 matching lines...) Expand all Loading... |
3701 has_seen_constructor_ = true; | 3712 has_seen_constructor_ = true; |
3702 return; | 3713 return; |
3703 } | 3714 } |
3704 } | 3715 } |
3705 | 3716 |
3706 | 3717 |
3707 } // namespace internal | 3718 } // namespace internal |
3708 } // namespace v8 | 3719 } // namespace v8 |
3709 | 3720 |
3710 #endif // V8_PARSING_PARSER_BASE_H | 3721 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |