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

Side by Side Diff: src/preparser.h

Issue 459463002: ES6: Duplicate properties are no longer an error (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add test for number literals that was previously part of duplicate property test Created 6 years, 4 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
« no previous file with comments | « no previous file | test/cctest/test-parsing.cc » ('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_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 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, 485 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
486 bool* ok); 486 bool* ok);
487 487
488 // Checks if the expression is a valid reference expression (e.g., on the 488 // Checks if the expression is a valid reference expression (e.g., on the
489 // left-hand side of assignments). Although ruled out by ECMA as early errors, 489 // left-hand side of assignments). Although ruled out by ECMA as early errors,
490 // we allow calls for web compatibility and rewrite them to a runtime throw. 490 // we allow calls for web compatibility and rewrite them to a runtime throw.
491 ExpressionT CheckAndRewriteReferenceExpression( 491 ExpressionT CheckAndRewriteReferenceExpression(
492 ExpressionT expression, 492 ExpressionT expression,
493 Scanner::Location location, const char* message, bool* ok); 493 Scanner::Location location, const char* message, bool* ok);
494 494
495 // Used to detect duplicates in object literals. Each of the values
496 // kGetterProperty, kSetterProperty and kValueProperty represents
497 // a type of object literal property. When parsing a property, its
498 // type value is stored in the DuplicateFinder for the property name.
499 // Values are chosen so that having intersection bits means the there is
500 // an incompatibility.
501 // I.e., you can add a getter to a property that already has a setter, since
502 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
503 // already has a getter or a value. Adding the getter to an existing
504 // setter will store the value (kGetterProperty | kSetterProperty), which
505 // is incompatible with adding any further properties.
506 enum PropertyKind {
507 kNone = 0,
508 // Bit patterns representing different object literal property types.
509 kGetterProperty = 1,
510 kSetterProperty = 2,
511 kValueProperty = 7,
512 // Helper constants.
513 kValueFlag = 4
514 };
515
516 // Validation per ECMA 262 - 11.1.5 "Object Initialiser".
517 class ObjectLiteralChecker {
518 public:
519 ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode)
520 : parser_(parser),
521 finder_(scanner()->unicode_cache()),
522 strict_mode_(strict_mode) { }
523
524 void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
525
526 private:
527 ParserBase* parser() const { return parser_; }
528 Scanner* scanner() const { return parser_->scanner(); }
529
530 // Checks the type of conflict based on values coming from PropertyType.
531 bool HasConflict(PropertyKind type1, PropertyKind type2) {
532 return (type1 & type2) != 0;
533 }
534 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
535 return ((type1 & type2) & kValueFlag) != 0;
536 }
537 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
538 return ((type1 ^ type2) & kValueFlag) != 0;
539 }
540 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
541 return ((type1 | type2) & kValueFlag) == 0;
542 }
543
544 ParserBase* parser_;
545 DuplicateFinder finder_;
546 StrictMode strict_mode_;
547 };
548
549 // If true, the next (and immediately following) function literal is 495 // If true, the next (and immediately following) function literal is
550 // preceded by a parenthesis. 496 // preceded by a parenthesis.
551 // Heuristically that means that the function will be called immediately, 497 // Heuristically that means that the function will be called immediately,
552 // so never lazily compile it. 498 // so never lazily compile it.
553 bool parenthesized_function_; 499 bool parenthesized_function_;
554 500
555 typename Traits::Type::Scope* scope_; // Scope stack. 501 typename Traits::Type::Scope* scope_; // Scope stack.
556 FunctionState* function_state_; // Function state stack. 502 FunctionState* function_state_; // Function state stack.
557 v8::Extension* extension_; 503 v8::Extension* extension_;
558 FuncNameInferrer* fni_; 504 FuncNameInferrer* fni_;
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1788 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1843 // ) ',')* '}' 1789 // ) ',')* '}'
1844 // (Except that the trailing comma is not required.) 1790 // (Except that the trailing comma is not required.)
1845 1791
1846 int pos = peek_position(); 1792 int pos = peek_position();
1847 typename Traits::Type::PropertyList properties = 1793 typename Traits::Type::PropertyList properties =
1848 this->NewPropertyList(4, zone_); 1794 this->NewPropertyList(4, zone_);
1849 int number_of_boilerplate_properties = 0; 1795 int number_of_boilerplate_properties = 0;
1850 bool has_function = false; 1796 bool has_function = false;
1851 1797
1852 ObjectLiteralChecker checker(this, strict_mode());
1853
1854 Expect(Token::LBRACE, CHECK_OK); 1798 Expect(Token::LBRACE, CHECK_OK);
1855 1799
1856 while (peek() != Token::RBRACE) { 1800 while (peek() != Token::RBRACE) {
1857 if (fni_ != NULL) fni_->Enter(); 1801 if (fni_ != NULL) fni_->Enter();
1858 1802
1859 typename Traits::Type::Literal key = this->EmptyLiteral(); 1803 typename Traits::Type::Literal key = this->EmptyLiteral();
1860 Token::Value next = peek(); 1804 Token::Value next = peek();
1861 int next_pos = peek_position(); 1805 int next_pos = peek_position();
1862 1806
1863 switch (next) { 1807 switch (next) {
(...skipping 18 matching lines...) Expand all
1882 next != i::Token::FUTURE_STRICT_RESERVED_WORD && 1826 next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1883 next != i::Token::LET && 1827 next != i::Token::LET &&
1884 next != i::Token::YIELD && 1828 next != i::Token::YIELD &&
1885 next != i::Token::NUMBER && 1829 next != i::Token::NUMBER &&
1886 next != i::Token::STRING && 1830 next != i::Token::STRING &&
1887 !Token::IsKeyword(next)) { 1831 !Token::IsKeyword(next)) {
1888 ReportUnexpectedToken(next); 1832 ReportUnexpectedToken(next);
1889 *ok = false; 1833 *ok = false;
1890 return this->EmptyLiteral(); 1834 return this->EmptyLiteral();
1891 } 1835 }
1892 // Validate the property.
1893 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1894 checker.CheckProperty(next, type, CHECK_OK);
1895 IdentifierT name = this->GetSymbol(scanner_); 1836 IdentifierT name = this->GetSymbol(scanner_);
1896 typename Traits::Type::FunctionLiteral value = 1837 typename Traits::Type::FunctionLiteral value =
1897 this->ParseFunctionLiteral( 1838 this->ParseFunctionLiteral(
1898 name, scanner()->location(), 1839 name, scanner()->location(),
1899 false, // reserved words are allowed here 1840 false, // reserved words are allowed here
1900 false, // not a generator 1841 false, // not a generator
1901 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 1842 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1902 is_getter ? FunctionLiteral::GETTER_ARITY 1843 is_getter ? FunctionLiteral::GETTER_ARITY
1903 : FunctionLiteral::SETTER_ARITY, 1844 : FunctionLiteral::SETTER_ARITY,
1904 CHECK_OK); 1845 CHECK_OK);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 IdentifierT string = this->GetSymbol(scanner_); 1889 IdentifierT string = this->GetSymbol(scanner_);
1949 key = factory()->NewStringLiteral(string, next_pos); 1890 key = factory()->NewStringLiteral(string, next_pos);
1950 } else { 1891 } else {
1951 Token::Value next = Next(); 1892 Token::Value next = Next();
1952 ReportUnexpectedToken(next); 1893 ReportUnexpectedToken(next);
1953 *ok = false; 1894 *ok = false;
1954 return this->EmptyLiteral(); 1895 return this->EmptyLiteral();
1955 } 1896 }
1956 } 1897 }
1957 1898
1958 // Validate the property
1959 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1960
1961 Expect(Token::COLON, CHECK_OK); 1899 Expect(Token::COLON, CHECK_OK);
1962 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK); 1900 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK);
1963 1901
1964 typename Traits::Type::ObjectLiteralProperty property = 1902 typename Traits::Type::ObjectLiteralProperty property =
1965 factory()->NewObjectLiteralProperty(key, value); 1903 factory()->NewObjectLiteralProperty(key, value);
1966 1904
1967 // Mark top-level object literals that contain function literals and 1905 // Mark top-level object literals that contain function literals and
1968 // pretenure the literal so it can be added as a constant function 1906 // pretenure the literal so it can be added as a constant function
1969 // property. (Parser only.) 1907 // property. (Parser only.)
1970 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value, 1908 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
2621 *ok = false; 2559 *ok = false;
2622 return this->EmptyExpression(); 2560 return this->EmptyExpression();
2623 } 2561 }
2624 } 2562 }
2625 2563
2626 2564
2627 #undef CHECK_OK 2565 #undef CHECK_OK
2628 #undef CHECK_OK_CUSTOM 2566 #undef CHECK_OK_CUSTOM
2629 2567
2630 2568
2631 template <typename Traits>
2632 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
2633 Token::Value property,
2634 PropertyKind type,
2635 bool* ok) {
2636 int old;
2637 if (property == Token::NUMBER) {
2638 old = scanner()->FindNumber(&finder_, type);
2639 } else {
2640 old = scanner()->FindSymbol(&finder_, type);
2641 }
2642 PropertyKind old_type = static_cast<PropertyKind>(old);
2643 if (HasConflict(old_type, type)) {
2644 if (IsDataDataConflict(old_type, type)) {
2645 // Both are data properties.
2646 if (strict_mode_ == SLOPPY) return;
2647 parser()->ReportMessage("strict_duplicate_property");
2648 } else if (IsDataAccessorConflict(old_type, type)) {
2649 // Both a data and an accessor property with the same name.
2650 parser()->ReportMessage("accessor_data_property");
2651 } else {
2652 DCHECK(IsAccessorAccessorConflict(old_type, type));
2653 // Both accessors of the same type.
2654 parser()->ReportMessage("accessor_get_set");
2655 }
2656 *ok = false;
2657 }
2658 }
2659
2660
2661 } } // v8::internal 2569 } } // v8::internal
2662 2570
2663 #endif // V8_PREPARSER_H 2571 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « no previous file | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698