OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 MessageTemplate::kUnexpectedToken, | 1332 MessageTemplate::kUnexpectedToken, |
1333 Token::String(Token::RPAREN)); | 1333 Token::String(Token::RPAREN)); |
1334 classifier->RecordBindingPatternError(scanner()->location(), | 1334 classifier->RecordBindingPatternError(scanner()->location(), |
1335 MessageTemplate::kUnexpectedToken, | 1335 MessageTemplate::kUnexpectedToken, |
1336 Token::String(Token::RPAREN)); | 1336 Token::String(Token::RPAREN)); |
1337 return factory()->NewEmptyParentheses(beg_pos); | 1337 return factory()->NewEmptyParentheses(beg_pos); |
1338 } else if (Check(Token::ELLIPSIS)) { | 1338 } else if (Check(Token::ELLIPSIS)) { |
1339 // (...x)=>x. The continuation that looks for the => is in | 1339 // (...x)=>x. The continuation that looks for the => is in |
1340 // ParseAssignmentExpression. | 1340 // ParseAssignmentExpression. |
1341 int ellipsis_pos = position(); | 1341 int ellipsis_pos = position(); |
| 1342 int expr_pos = peek_position(); |
1342 classifier->RecordExpressionError(scanner()->location(), | 1343 classifier->RecordExpressionError(scanner()->location(), |
1343 MessageTemplate::kUnexpectedToken, | 1344 MessageTemplate::kUnexpectedToken, |
1344 Token::String(Token::ELLIPSIS)); | 1345 Token::String(Token::ELLIPSIS)); |
1345 classifier->RecordNonSimpleParameter(); | 1346 classifier->RecordNonSimpleParameter(); |
1346 ExpressionT expr = | 1347 ExpressionT expr = |
1347 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1348 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
1348 if (peek() == Token::COMMA) { | 1349 if (peek() == Token::COMMA) { |
1349 ReportMessageAt(scanner()->peek_location(), | 1350 ReportMessageAt(scanner()->peek_location(), |
1350 MessageTemplate::kParamAfterRest); | 1351 MessageTemplate::kParamAfterRest); |
1351 *ok = false; | 1352 *ok = false; |
1352 return this->EmptyExpression(); | 1353 return this->EmptyExpression(); |
1353 } | 1354 } |
1354 Expect(Token::RPAREN, CHECK_OK); | 1355 Expect(Token::RPAREN, CHECK_OK); |
1355 return factory()->NewSpread(expr, ellipsis_pos); | 1356 return factory()->NewSpread(expr, ellipsis_pos, expr_pos); |
1356 } | 1357 } |
1357 // Heuristically try to detect immediately called functions before | 1358 // Heuristically try to detect immediately called functions before |
1358 // seeing the call parentheses. | 1359 // seeing the call parentheses. |
1359 parenthesized_function_ = (peek() == Token::FUNCTION); | 1360 parenthesized_function_ = (peek() == Token::FUNCTION); |
1360 ExpressionT expr = this->ParseExpression(true, kIsPossibleArrowFormals, | 1361 ExpressionT expr = this->ParseExpression(true, kIsPossibleArrowFormals, |
1361 classifier, CHECK_OK); | 1362 classifier, CHECK_OK); |
1362 Expect(Token::RPAREN, CHECK_OK); | 1363 Expect(Token::RPAREN, CHECK_OK); |
1363 if (peek() != Token::ARROW) { | 1364 if (peek() != Token::ARROW) { |
1364 expr->set_is_parenthesized(); | 1365 expr->set_is_parenthesized(); |
1365 } | 1366 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 bool is_rest = false; | 1463 bool is_rest = false; |
1463 if (peek() == Token::ELLIPSIS) { | 1464 if (peek() == Token::ELLIPSIS) { |
1464 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1465 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
1465 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 1466 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
1466 // valid expression or binding pattern. | 1467 // valid expression or binding pattern. |
1467 ExpressionUnexpectedToken(classifier); | 1468 ExpressionUnexpectedToken(classifier); |
1468 BindingPatternUnexpectedToken(classifier); | 1469 BindingPatternUnexpectedToken(classifier); |
1469 Consume(Token::ELLIPSIS); | 1470 Consume(Token::ELLIPSIS); |
1470 seen_rest = is_rest = true; | 1471 seen_rest = is_rest = true; |
1471 } | 1472 } |
1472 int pos = position(); | 1473 int pos = position(), expr_pos = peek_position(); |
1473 ExpressionT right = this->ParseAssignmentExpression( | 1474 ExpressionT right = this->ParseAssignmentExpression( |
1474 accept_IN, flags, &binding_classifier, CHECK_OK); | 1475 accept_IN, flags, &binding_classifier, CHECK_OK); |
1475 if (is_rest) right = factory()->NewSpread(right, pos); | 1476 if (is_rest) right = factory()->NewSpread(right, pos, expr_pos); |
1476 is_simple_parameter_list = | 1477 is_simple_parameter_list = |
1477 is_simple_parameter_list && this->IsIdentifier(right); | 1478 is_simple_parameter_list && this->IsIdentifier(right); |
1478 classifier->Accumulate(binding_classifier, | 1479 classifier->Accumulate(binding_classifier, |
1479 ExpressionClassifier::AllProductions); | 1480 ExpressionClassifier::AllProductions); |
1480 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 1481 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
1481 } | 1482 } |
1482 if (!is_simple_parameter_list || seen_rest) { | 1483 if (!is_simple_parameter_list || seen_rest) { |
1483 classifier->RecordNonSimpleParameter(); | 1484 classifier->RecordNonSimpleParameter(); |
1484 } | 1485 } |
1485 | 1486 |
(...skipping 18 matching lines...) Expand all Loading... |
1504 if (is_strong(language_mode())) { | 1505 if (is_strong(language_mode())) { |
1505 ReportMessageAt(scanner()->peek_location(), | 1506 ReportMessageAt(scanner()->peek_location(), |
1506 MessageTemplate::kStrongEllision); | 1507 MessageTemplate::kStrongEllision); |
1507 *ok = false; | 1508 *ok = false; |
1508 return this->EmptyExpression(); | 1509 return this->EmptyExpression(); |
1509 } | 1510 } |
1510 elem = this->GetLiteralTheHole(peek_position(), factory()); | 1511 elem = this->GetLiteralTheHole(peek_position(), factory()); |
1511 } else if (peek() == Token::ELLIPSIS) { | 1512 } else if (peek() == Token::ELLIPSIS) { |
1512 int start_pos = peek_position(); | 1513 int start_pos = peek_position(); |
1513 Consume(Token::ELLIPSIS); | 1514 Consume(Token::ELLIPSIS); |
| 1515 int expr_pos = peek_position(); |
1514 ExpressionT argument = | 1516 ExpressionT argument = |
1515 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1517 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
1516 elem = factory()->NewSpread(argument, start_pos); | 1518 elem = factory()->NewSpread(argument, start_pos, expr_pos); |
1517 | 1519 |
1518 if (first_spread_index < 0) { | 1520 if (first_spread_index < 0) { |
1519 first_spread_index = values->length(); | 1521 first_spread_index = values->length(); |
1520 } | 1522 } |
1521 | 1523 |
1522 if (argument->IsAssignment()) { | 1524 if (argument->IsAssignment()) { |
1523 classifier->RecordPatternError( | 1525 classifier->RecordPatternError( |
1524 Scanner::Location(start_pos, scanner()->location().end_pos), | 1526 Scanner::Location(start_pos, scanner()->location().end_pos), |
1525 MessageTemplate::kInvalidDestructuringTarget); | 1527 MessageTemplate::kInvalidDestructuringTarget); |
1526 } else { | 1528 } else { |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1906 Scanner::Location spread_arg = Scanner::Location::invalid(); | 1908 Scanner::Location spread_arg = Scanner::Location::invalid(); |
1907 typename Traits::Type::ExpressionList result = | 1909 typename Traits::Type::ExpressionList result = |
1908 this->NewExpressionList(4, zone_); | 1910 this->NewExpressionList(4, zone_); |
1909 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1911 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1910 bool done = (peek() == Token::RPAREN); | 1912 bool done = (peek() == Token::RPAREN); |
1911 bool was_unspread = false; | 1913 bool was_unspread = false; |
1912 int unspread_sequences_count = 0; | 1914 int unspread_sequences_count = 0; |
1913 while (!done) { | 1915 while (!done) { |
1914 int start_pos = peek_position(); | 1916 int start_pos = peek_position(); |
1915 bool is_spread = Check(Token::ELLIPSIS); | 1917 bool is_spread = Check(Token::ELLIPSIS); |
| 1918 int expr_pos = peek_position(); |
1916 | 1919 |
1917 ExpressionT argument = this->ParseAssignmentExpression( | 1920 ExpressionT argument = this->ParseAssignmentExpression( |
1918 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 1921 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
1919 argument = Traits::RewriteNonPattern(argument, classifier, | 1922 argument = Traits::RewriteNonPattern(argument, classifier, |
1920 CHECK_OK_CUSTOM(NullExpressionList)); | 1923 CHECK_OK_CUSTOM(NullExpressionList)); |
1921 if (is_spread) { | 1924 if (is_spread) { |
1922 if (!spread_arg.IsValid()) { | 1925 if (!spread_arg.IsValid()) { |
1923 spread_arg.beg_pos = start_pos; | 1926 spread_arg.beg_pos = start_pos; |
1924 spread_arg.end_pos = peek_position(); | 1927 spread_arg.end_pos = peek_position(); |
1925 } | 1928 } |
1926 argument = factory()->NewSpread(argument, start_pos); | 1929 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
1927 } | 1930 } |
1928 result->Add(argument, zone_); | 1931 result->Add(argument, zone_); |
1929 | 1932 |
1930 // unspread_sequences_count is the number of sequences of parameters which | 1933 // unspread_sequences_count is the number of sequences of parameters which |
1931 // are not prefixed with a spread '...' operator. | 1934 // are not prefixed with a spread '...' operator. |
1932 if (is_spread) { | 1935 if (is_spread) { |
1933 was_unspread = false; | 1936 was_unspread = false; |
1934 } else if (!was_unspread) { | 1937 } else if (!was_unspread) { |
1935 was_unspread = true; | 1938 was_unspread = true; |
1936 unspread_sequences_count++; | 1939 unspread_sequences_count++; |
(...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3371 return; | 3374 return; |
3372 } | 3375 } |
3373 has_seen_constructor_ = true; | 3376 has_seen_constructor_ = true; |
3374 return; | 3377 return; |
3375 } | 3378 } |
3376 } | 3379 } |
3377 } // namespace internal | 3380 } // namespace internal |
3378 } // namespace v8 | 3381 } // namespace v8 |
3379 | 3382 |
3380 #endif // V8_PARSING_PARSER_BASE_H | 3383 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |