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

Side by Side Diff: src/preparser.h

Issue 378303003: Make `let` usable as an identifier in ES6 sloppy mode. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments Created 6 years, 5 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 | Annotate | Revision Log
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_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 return; 294 return;
295 } 295 }
296 Expect(Token::SEMICOLON, ok); 296 Expect(Token::SEMICOLON, ok);
297 } 297 }
298 298
299 bool peek_any_identifier() { 299 bool peek_any_identifier() {
300 Token::Value next = peek(); 300 Token::Value next = peek();
301 return next == Token::IDENTIFIER || 301 return next == Token::IDENTIFIER ||
302 next == Token::FUTURE_RESERVED_WORD || 302 next == Token::FUTURE_RESERVED_WORD ||
303 next == Token::FUTURE_STRICT_RESERVED_WORD || 303 next == Token::FUTURE_STRICT_RESERVED_WORD ||
304 next == Token::LET ||
304 next == Token::YIELD; 305 next == Token::YIELD;
305 } 306 }
306 307
307 bool CheckContextualKeyword(Vector<const char> keyword) { 308 bool CheckContextualKeyword(Vector<const char> keyword) {
308 if (peek() == Token::IDENTIFIER && 309 if (peek() == Token::IDENTIFIER &&
309 scanner()->is_next_contextual_keyword(keyword)) { 310 scanner()->is_next_contextual_keyword(keyword)) {
310 Consume(Token::IDENTIFIER); 311 Consume(Token::IDENTIFIER);
311 return true; 312 return true;
312 } 313 }
313 return false; 314 return false;
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 } 542 }
542 static PreParserIdentifier Arguments() { 543 static PreParserIdentifier Arguments() {
543 return PreParserIdentifier(kArgumentsIdentifier); 544 return PreParserIdentifier(kArgumentsIdentifier);
544 } 545 }
545 static PreParserIdentifier FutureReserved() { 546 static PreParserIdentifier FutureReserved() {
546 return PreParserIdentifier(kFutureReservedIdentifier); 547 return PreParserIdentifier(kFutureReservedIdentifier);
547 } 548 }
548 static PreParserIdentifier FutureStrictReserved() { 549 static PreParserIdentifier FutureStrictReserved() {
549 return PreParserIdentifier(kFutureStrictReservedIdentifier); 550 return PreParserIdentifier(kFutureStrictReservedIdentifier);
550 } 551 }
552 static PreParserIdentifier Let() {
553 return PreParserIdentifier(kLetIdentifier);
554 }
551 static PreParserIdentifier Yield() { 555 static PreParserIdentifier Yield() {
552 return PreParserIdentifier(kYieldIdentifier); 556 return PreParserIdentifier(kYieldIdentifier);
553 } 557 }
554 bool IsEval() { return type_ == kEvalIdentifier; } 558 bool IsEval() { return type_ == kEvalIdentifier; }
555 bool IsArguments() { return type_ == kArgumentsIdentifier; } 559 bool IsArguments() { return type_ == kArgumentsIdentifier; }
556 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } 560 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
561 bool IsLet() { return type_ == kLetIdentifier; }
557 bool IsYield() { return type_ == kYieldIdentifier; } 562 bool IsYield() { return type_ == kYieldIdentifier; }
558 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } 563 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
559 bool IsFutureStrictReserved() { 564 bool IsFutureStrictReserved() {
560 return type_ == kFutureStrictReservedIdentifier; 565 return type_ == kFutureStrictReservedIdentifier;
561 } 566 }
562 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 567 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
563 568
564 private: 569 private:
565 enum Type { 570 enum Type {
566 kUnknownIdentifier, 571 kUnknownIdentifier,
567 kFutureReservedIdentifier, 572 kFutureReservedIdentifier,
568 kFutureStrictReservedIdentifier, 573 kFutureStrictReservedIdentifier,
574 kLetIdentifier,
569 kYieldIdentifier, 575 kYieldIdentifier,
570 kEvalIdentifier, 576 kEvalIdentifier,
571 kArgumentsIdentifier 577 kArgumentsIdentifier
572 }; 578 };
573 explicit PreParserIdentifier(Type type) : type_(type) {} 579 explicit PreParserIdentifier(Type type) : type_(type) {}
574 Type type_; 580 Type type_;
575 581
576 friend class PreParserExpression; 582 friend class PreParserExpression;
577 }; 583 };
578 584
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 case Token::EOS: 1270 case Token::EOS:
1265 return ReportMessageAt(source_location, "unexpected_eos"); 1271 return ReportMessageAt(source_location, "unexpected_eos");
1266 case Token::NUMBER: 1272 case Token::NUMBER:
1267 return ReportMessageAt(source_location, "unexpected_token_number"); 1273 return ReportMessageAt(source_location, "unexpected_token_number");
1268 case Token::STRING: 1274 case Token::STRING:
1269 return ReportMessageAt(source_location, "unexpected_token_string"); 1275 return ReportMessageAt(source_location, "unexpected_token_string");
1270 case Token::IDENTIFIER: 1276 case Token::IDENTIFIER:
1271 return ReportMessageAt(source_location, "unexpected_token_identifier"); 1277 return ReportMessageAt(source_location, "unexpected_token_identifier");
1272 case Token::FUTURE_RESERVED_WORD: 1278 case Token::FUTURE_RESERVED_WORD:
1273 return ReportMessageAt(source_location, "unexpected_reserved"); 1279 return ReportMessageAt(source_location, "unexpected_reserved");
1280 case Token::LET:
1274 case Token::YIELD: 1281 case Token::YIELD:
1275 case Token::FUTURE_STRICT_RESERVED_WORD: 1282 case Token::FUTURE_STRICT_RESERVED_WORD:
1276 return ReportMessageAt(source_location, strict_mode() == SLOPPY 1283 return ReportMessageAt(source_location, strict_mode() == SLOPPY
1277 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); 1284 ? "unexpected_token_identifier" : "unexpected_strict_reserved");
1278 default: 1285 default:
1279 const char* name = Token::String(token); 1286 const char* name = Token::String(token);
1280 ASSERT(name != NULL); 1287 ASSERT(name != NULL);
1281 Traits::ReportMessageAt(source_location, "unexpected_token", name); 1288 Traits::ReportMessageAt(source_location, "unexpected_token", name);
1282 } 1289 }
1283 } 1290 }
1284 1291
1285 1292
1286 template<class Traits> 1293 template<class Traits>
1287 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1294 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
1288 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1295 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1289 bool* ok) { 1296 bool* ok) {
1290 Token::Value next = Next(); 1297 Token::Value next = Next();
1291 if (next == Token::IDENTIFIER) { 1298 if (next == Token::IDENTIFIER) {
1292 IdentifierT name = this->GetSymbol(scanner()); 1299 IdentifierT name = this->GetSymbol(scanner());
1293 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 1300 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
1294 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { 1301 strict_mode() == STRICT && this->IsEvalOrArguments(name)) {
1295 ReportMessage("strict_eval_arguments"); 1302 ReportMessage("strict_eval_arguments");
1296 *ok = false; 1303 *ok = false;
1297 } 1304 }
1298 return name; 1305 return name;
1299 } else if (strict_mode() == SLOPPY && 1306 } else if (strict_mode() == SLOPPY &&
1300 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1307 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1308 (next == Token::LET) ||
1301 (next == Token::YIELD && !is_generator()))) { 1309 (next == Token::YIELD && !is_generator()))) {
1302 return this->GetSymbol(scanner()); 1310 return this->GetSymbol(scanner());
1303 } else { 1311 } else {
1304 this->ReportUnexpectedToken(next); 1312 this->ReportUnexpectedToken(next);
1305 *ok = false; 1313 *ok = false;
1306 return Traits::EmptyIdentifier(); 1314 return Traits::EmptyIdentifier();
1307 } 1315 }
1308 } 1316 }
1309 1317
1310 1318
1311 template <class Traits> 1319 template <class Traits>
1312 typename ParserBase<Traits>::IdentifierT ParserBase< 1320 typename ParserBase<Traits>::IdentifierT ParserBase<
1313 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, 1321 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1314 bool* ok) { 1322 bool* ok) {
1315 Token::Value next = Next(); 1323 Token::Value next = Next();
1316 if (next == Token::IDENTIFIER) { 1324 if (next == Token::IDENTIFIER) {
1317 *is_strict_reserved = false; 1325 *is_strict_reserved = false;
1318 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || 1326 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1327 next == Token::LET ||
1319 (next == Token::YIELD && !this->is_generator())) { 1328 (next == Token::YIELD && !this->is_generator())) {
1320 *is_strict_reserved = true; 1329 *is_strict_reserved = true;
1321 } else { 1330 } else {
1322 ReportUnexpectedToken(next); 1331 ReportUnexpectedToken(next);
1323 *ok = false; 1332 *ok = false;
1324 return Traits::EmptyIdentifier(); 1333 return Traits::EmptyIdentifier();
1325 } 1334 }
1326 return this->GetSymbol(scanner()); 1335 return this->GetSymbol(scanner());
1327 } 1336 }
1328 1337
1329 1338
1330 template <class Traits> 1339 template <class Traits>
1331 typename ParserBase<Traits>::IdentifierT 1340 typename ParserBase<Traits>::IdentifierT
1332 ParserBase<Traits>::ParseIdentifierName(bool* ok) { 1341 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
1333 Token::Value next = Next(); 1342 Token::Value next = Next();
1334 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && 1343 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
1344 next != Token::LET && next != Token::YIELD &&
1335 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 1345 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1336 this->ReportUnexpectedToken(next); 1346 this->ReportUnexpectedToken(next);
1337 *ok = false; 1347 *ok = false;
1338 return Traits::EmptyIdentifier(); 1348 return Traits::EmptyIdentifier();
1339 } 1349 }
1340 return this->GetSymbol(scanner()); 1350 return this->GetSymbol(scanner());
1341 } 1351 }
1342 1352
1343 1353
1344 template <class Traits> 1354 template <class Traits>
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 1430
1421 case Token::NULL_LITERAL: 1431 case Token::NULL_LITERAL:
1422 case Token::TRUE_LITERAL: 1432 case Token::TRUE_LITERAL:
1423 case Token::FALSE_LITERAL: 1433 case Token::FALSE_LITERAL:
1424 case Token::NUMBER: 1434 case Token::NUMBER:
1425 Next(); 1435 Next();
1426 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); 1436 result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
1427 break; 1437 break;
1428 1438
1429 case Token::IDENTIFIER: 1439 case Token::IDENTIFIER:
1440 case Token::LET:
1430 case Token::YIELD: 1441 case Token::YIELD:
1431 case Token::FUTURE_STRICT_RESERVED_WORD: { 1442 case Token::FUTURE_STRICT_RESERVED_WORD: {
1432 // Using eval or arguments in this context is OK even in strict mode. 1443 // Using eval or arguments in this context is OK even in strict mode.
1433 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1444 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1434 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); 1445 result = this->ExpressionFromIdentifier(name, pos, scope_, factory());
1435 break; 1446 break;
1436 } 1447 }
1437 1448
1438 case Token::STRING: { 1449 case Token::STRING: {
1439 Consume(Token::STRING); 1450 Consume(Token::STRING);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 while (peek() != Token::RBRACE) { 1568 while (peek() != Token::RBRACE) {
1558 if (fni_ != NULL) fni_->Enter(); 1569 if (fni_ != NULL) fni_->Enter();
1559 1570
1560 typename Traits::Type::Literal key = this->EmptyLiteral(); 1571 typename Traits::Type::Literal key = this->EmptyLiteral();
1561 Token::Value next = peek(); 1572 Token::Value next = peek();
1562 int next_pos = peek_position(); 1573 int next_pos = peek_position();
1563 1574
1564 switch (next) { 1575 switch (next) {
1565 case Token::FUTURE_RESERVED_WORD: 1576 case Token::FUTURE_RESERVED_WORD:
1566 case Token::FUTURE_STRICT_RESERVED_WORD: 1577 case Token::FUTURE_STRICT_RESERVED_WORD:
1578 case Token::LET:
1579 case Token::YIELD:
1567 case Token::IDENTIFIER: { 1580 case Token::IDENTIFIER: {
1568 bool is_getter = false; 1581 bool is_getter = false;
1569 bool is_setter = false; 1582 bool is_setter = false;
1570 IdentifierT id = 1583 IdentifierT id =
1571 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1584 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1572 if (fni_ != NULL) this->PushLiteralName(fni_, id); 1585 if (fni_ != NULL) this->PushLiteralName(fni_, id);
1573 1586
1574 if ((is_getter || is_setter) && peek() != Token::COLON) { 1587 if ((is_getter || is_setter) && peek() != Token::COLON) {
1575 // Special handling of getter and setter syntax: 1588 // Special handling of getter and setter syntax:
1576 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 1589 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
1577 // We have already read the "get" or "set" keyword. 1590 // We have already read the "get" or "set" keyword.
1578 Token::Value next = Next(); 1591 Token::Value next = Next();
1579 if (next != i::Token::IDENTIFIER && 1592 if (next != i::Token::IDENTIFIER &&
1580 next != i::Token::FUTURE_RESERVED_WORD && 1593 next != i::Token::FUTURE_RESERVED_WORD &&
1581 next != i::Token::FUTURE_STRICT_RESERVED_WORD && 1594 next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1595 next != i::Token::LET &&
1596 next != i::Token::YIELD &&
1582 next != i::Token::NUMBER && 1597 next != i::Token::NUMBER &&
1583 next != i::Token::STRING && 1598 next != i::Token::STRING &&
1584 !Token::IsKeyword(next)) { 1599 !Token::IsKeyword(next)) {
1585 ReportUnexpectedToken(next); 1600 ReportUnexpectedToken(next);
1586 *ok = false; 1601 *ok = false;
1587 return this->EmptyLiteral(); 1602 return this->EmptyLiteral();
1588 } 1603 }
1589 // Validate the property. 1604 // Validate the property.
1590 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1605 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1591 checker.CheckProperty(next, type, CHECK_OK); 1606 checker.CheckProperty(next, type, CHECK_OK);
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
2226 parser()->ReportMessage("accessor_get_set"); 2241 parser()->ReportMessage("accessor_get_set");
2227 } 2242 }
2228 *ok = false; 2243 *ok = false;
2229 } 2244 }
2230 } 2245 }
2231 2246
2232 2247
2233 } } // v8::internal 2248 } } // v8::internal
2234 2249
2235 #endif // V8_PREPARSER_H 2250 #endif // V8_PREPARSER_H
OLDNEW
« src/parser.cc ('K') | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698