Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: src/parsing/parser-base.h

Issue 2267663002: [parser] Apply an adaptation of the CRTP (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@nickie-2263973003-add-const
Patch Set: Formatting Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698