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

Side by Side Diff: src/preparser.h

Issue 677953004: Allow duplicate property names in classes (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove out dated comment and add/fix assert Created 6 years, 1 month 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 | « src/messages.js ('k') | 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/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); 469 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
470 470
471 ExpressionT ParsePrimaryExpression(bool* ok); 471 ExpressionT ParsePrimaryExpression(bool* ok);
472 ExpressionT ParseExpression(bool accept_IN, bool* ok); 472 ExpressionT ParseExpression(bool accept_IN, bool* ok);
473 ExpressionT ParseArrayLiteral(bool* ok); 473 ExpressionT ParseArrayLiteral(bool* ok);
474 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static, 474 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static,
475 bool* ok); 475 bool* ok);
476 ExpressionT ParseObjectLiteral(bool* ok); 476 ExpressionT ParseObjectLiteral(bool* ok);
477 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, 477 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker,
478 bool in_class, bool is_static, 478 bool in_class, bool is_static,
479 bool* has_seen_constructor,
479 bool* ok); 480 bool* ok);
480 typename Traits::Type::ExpressionList ParseArguments(bool* ok); 481 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
481 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); 482 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
482 ExpressionT ParseYieldExpression(bool* ok); 483 ExpressionT ParseYieldExpression(bool* ok);
483 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 484 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
484 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 485 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
485 ExpressionT ParseUnaryExpression(bool* ok); 486 ExpressionT ParseUnaryExpression(bool* ok);
486 ExpressionT ParsePostfixExpression(bool* ok); 487 ExpressionT ParsePostfixExpression(bool* ok);
487 ExpressionT ParseLeftHandSideExpression(bool* ok); 488 ExpressionT ParseLeftHandSideExpression(bool* ok);
488 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 489 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 1177
1177 static bool IsBoilerplateProperty(PreParserExpression property) { 1178 static bool IsBoilerplateProperty(PreParserExpression property) {
1178 // PreParser doesn't count boilerplate properties. 1179 // PreParser doesn't count boilerplate properties.
1179 return false; 1180 return false;
1180 } 1181 }
1181 1182
1182 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 1183 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
1183 return false; 1184 return false;
1184 } 1185 }
1185 1186
1186 bool IsConstructorProperty(PreParserExpression property) { return false; }
1187
1188 static PreParserExpression GetPropertyValue(PreParserExpression property) { 1187 static PreParserExpression GetPropertyValue(PreParserExpression property) {
1189 UNREACHABLE();
1190 return PreParserExpression::Default(); 1188 return PreParserExpression::Default();
1191 } 1189 }
1192 1190
1193 // Functions for encapsulating the differences between parsing and preparsing; 1191 // Functions for encapsulating the differences between parsing and preparsing;
1194 // operations interleaved with the recursive descent. 1192 // operations interleaved with the recursive descent.
1195 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 1193 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1196 // PreParser should not use FuncNameInferrer. 1194 // PreParser should not use FuncNameInferrer.
1197 UNREACHABLE(); 1195 UNREACHABLE();
1198 } 1196 }
1199 static void PushPropertyName(FuncNameInferrer* fni, 1197 static void PushPropertyName(FuncNameInferrer* fni,
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
1918 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); 1916 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok);
1919 } 1917 }
1920 UNREACHABLE(); 1918 UNREACHABLE();
1921 return this->EmptyIdentifier(); 1919 return this->EmptyIdentifier();
1922 } 1920 }
1923 1921
1924 1922
1925 template <class Traits> 1923 template <class Traits>
1926 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< 1924 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
1927 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, 1925 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker,
1928 bool in_class, bool is_static, bool* ok) { 1926 bool in_class, bool is_static,
1927 bool* has_seen_constructor, bool* ok) {
1928 DCHECK(!in_class || is_static || has_seen_constructor != NULL);
1929 ExpressionT value = this->EmptyExpression(); 1929 ExpressionT value = this->EmptyExpression();
1930 bool is_get = false; 1930 bool is_get = false;
1931 bool is_set = false; 1931 bool is_set = false;
1932 bool name_is_static = false; 1932 bool name_is_static = false;
1933 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); 1933 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
1934 1934
1935 Token::Value name_token = peek(); 1935 Token::Value name_token = peek();
1936 int next_pos = peek_position(); 1936 int next_pos = peek_position();
1937 IdentifierT name = 1937 IdentifierT name =
1938 ParsePropertyName(&is_get, &is_set, &name_is_static, 1938 ParsePropertyName(&is_get, &is_set, &name_is_static,
1939 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1939 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1940 1940
1941 if (fni_ != NULL) this->PushLiteralName(fni_, name); 1941 if (fni_ != NULL) this->PushLiteralName(fni_, name);
1942 1942
1943 if (!in_class && !is_generator && peek() == Token::COLON) { 1943 if (!in_class && !is_generator && peek() == Token::COLON) {
1944 // PropertyDefinition : PropertyName ':' AssignmentExpression 1944 // PropertyDefinition : PropertyName ':' AssignmentExpression
1945 checker->CheckProperty(name_token, kValueProperty, 1945 if (checker != NULL) {
1946 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1946 checker->CheckProperty(name_token, kValueProperty,
1947 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1948 }
1947 Consume(Token::COLON); 1949 Consume(Token::COLON);
1948 value = this->ParseAssignmentExpression( 1950 value = this->ParseAssignmentExpression(
1949 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1951 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1950 1952
1951 } else if (is_generator || 1953 } else if (is_generator ||
1952 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { 1954 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
1953 // Concise Method 1955 // Concise Method
1954 1956
1955 if (is_static && this->IsPrototype(name)) { 1957 if (is_static && this->IsPrototype(name)) {
1956 ReportMessageAt(scanner()->location(), "static_prototype"); 1958 ReportMessageAt(scanner()->location(), "static_prototype");
1957 *ok = false; 1959 *ok = false;
1958 return this->EmptyObjectLiteralProperty(); 1960 return this->EmptyObjectLiteralProperty();
1959 } 1961 }
1960 1962
1961 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod 1963 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
1962 : FunctionKind::kConciseMethod; 1964 : FunctionKind::kConciseMethod;
1963 1965
1964 if (in_class && !is_static && this->IsConstructor(name)) { 1966 if (in_class && !is_static && this->IsConstructor(name)) {
1965 if (is_generator) { 1967 if (is_generator) {
1966 ReportMessageAt(scanner()->location(), "constructor_special_method"); 1968 ReportMessageAt(scanner()->location(), "constructor_special_method");
1967 *ok = false; 1969 *ok = false;
1968 return this->EmptyObjectLiteralProperty(); 1970 return this->EmptyObjectLiteralProperty();
1969 } 1971 }
1970 1972
1973 if (*has_seen_constructor) {
1974 ReportMessageAt(scanner()->location(), "duplicate_constructor");
1975 *ok = false;
1976 return this->EmptyObjectLiteralProperty();
1977 }
1978
1979 *has_seen_constructor = true;
1971 kind = FunctionKind::kNormalFunction; 1980 kind = FunctionKind::kNormalFunction;
1972 } 1981 }
1973 1982
1974 checker->CheckProperty(name_token, kValueProperty, 1983 if (checker != NULL) {
1975 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1984 checker->CheckProperty(name_token, kValueProperty,
1985 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1986 }
1976 1987
1977 value = this->ParseFunctionLiteral( 1988 value = this->ParseFunctionLiteral(
1978 name, scanner()->location(), 1989 name, scanner()->location(),
1979 false, // reserved words are allowed here 1990 false, // reserved words are allowed here
1980 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 1991 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1981 FunctionLiteral::NORMAL_ARITY, 1992 FunctionLiteral::NORMAL_ARITY,
1982 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1993 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1983 1994
1984 } else if (in_class && name_is_static && !is_static) { 1995 } else if (in_class && name_is_static && !is_static) {
1985 // static MethodDefinition 1996 // static MethodDefinition
1986 return ParsePropertyDefinition(checker, true, true, ok); 1997 return ParsePropertyDefinition(checker, true, true, NULL, ok);
1987 1998
1988 } else if (is_get || is_set) { 1999 } else if (is_get || is_set) {
1989 // Accessor 2000 // Accessor
1990 bool dont_care = false; 2001 bool dont_care = false;
1991 name_token = peek(); 2002 name_token = peek();
1992 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, 2003 name = ParsePropertyName(&dont_care, &dont_care, &dont_care,
1993 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2004 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1994 2005
1995 // Validate the property. 2006 // Validate the property.
1996 if (is_static && this->IsPrototype(name)) { 2007 if (is_static && this->IsPrototype(name)) {
1997 ReportMessageAt(scanner()->location(), "static_prototype"); 2008 ReportMessageAt(scanner()->location(), "static_prototype");
1998 *ok = false; 2009 *ok = false;
1999 return this->EmptyObjectLiteralProperty(); 2010 return this->EmptyObjectLiteralProperty();
2000 } else if (in_class && !is_static && this->IsConstructor(name)) { 2011 } else if (in_class && !is_static && this->IsConstructor(name)) {
2001 // ES6, spec draft rev 27, treats static get constructor as an error too.
2002 // https://bugs.ecmascript.org/show_bug.cgi?id=3223
2003 // TODO(arv): Update when bug is resolved.
2004 ReportMessageAt(scanner()->location(), "constructor_special_method"); 2012 ReportMessageAt(scanner()->location(), "constructor_special_method");
2005 *ok = false; 2013 *ok = false;
2006 return this->EmptyObjectLiteralProperty(); 2014 return this->EmptyObjectLiteralProperty();
2007 } 2015 }
2008 checker->CheckProperty(name_token, 2016 if (checker != NULL) {
2009 is_get ? kGetterProperty : kSetterProperty, 2017 checker->CheckProperty(name_token,
2010 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2018 is_get ? kGetterProperty : kSetterProperty,
2019 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2020 }
2011 2021
2012 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2022 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2013 name, scanner()->location(), 2023 name, scanner()->location(),
2014 false, // reserved words are allowed here 2024 false, // reserved words are allowed here
2015 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, 2025 FunctionKind::kNormalFunction, RelocInfo::kNoPosition,
2016 FunctionLiteral::ANONYMOUS_EXPRESSION, 2026 FunctionLiteral::ANONYMOUS_EXPRESSION,
2017 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, 2027 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2018 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2028 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2019 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, 2029 return factory()->NewObjectLiteralProperty(is_get, value, next_pos,
2020 is_static); 2030 is_static);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 2064
2055 ObjectLiteralChecker checker(this, strict_mode()); 2065 ObjectLiteralChecker checker(this, strict_mode());
2056 2066
2057 Expect(Token::LBRACE, CHECK_OK); 2067 Expect(Token::LBRACE, CHECK_OK);
2058 2068
2059 while (peek() != Token::RBRACE) { 2069 while (peek() != Token::RBRACE) {
2060 if (fni_ != NULL) fni_->Enter(); 2070 if (fni_ != NULL) fni_->Enter();
2061 2071
2062 const bool in_class = false; 2072 const bool in_class = false;
2063 const bool is_static = false; 2073 const bool is_static = false;
2064 ObjectLiteralPropertyT property = 2074 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2065 this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); 2075 &checker, in_class, is_static, NULL, CHECK_OK);
2066 2076
2067 // Mark top-level object literals that contain function literals and 2077 // Mark top-level object literals that contain function literals and
2068 // pretenure the literal so it can be added as a constant function 2078 // pretenure the literal so it can be added as a constant function
2069 // property. (Parser only.) 2079 // property. (Parser only.)
2070 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, 2080 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2071 &has_function); 2081 &has_function);
2072 2082
2073 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 2083 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2074 if (this->IsBoilerplateProperty(property)) { 2084 if (this->IsBoilerplateProperty(property)) {
2075 number_of_boilerplate_properties++; 2085 number_of_boilerplate_properties++;
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
2737 scope_->SetStrictMode(STRICT); 2747 scope_->SetStrictMode(STRICT);
2738 extends = this->ParseLeftHandSideExpression(CHECK_OK); 2748 extends = this->ParseLeftHandSideExpression(CHECK_OK);
2739 } 2749 }
2740 2750
2741 // TODO(arv): Implement scopes and name binding in class body only. 2751 // TODO(arv): Implement scopes and name binding in class body only.
2742 typename Traits::Type::ScopePtr scope = this->NewScope(scope_, BLOCK_SCOPE); 2752 typename Traits::Type::ScopePtr scope = this->NewScope(scope_, BLOCK_SCOPE);
2743 BlockState block_state(&scope_, Traits::Type::ptr_to_scope(scope)); 2753 BlockState block_state(&scope_, Traits::Type::ptr_to_scope(scope));
2744 scope_->SetStrictMode(STRICT); 2754 scope_->SetStrictMode(STRICT);
2745 scope_->SetScopeName(name); 2755 scope_->SetScopeName(name);
2746 2756
2747 ObjectLiteralChecker checker(this, STRICT);
2748 typename Traits::Type::PropertyList properties = 2757 typename Traits::Type::PropertyList properties =
2749 this->NewPropertyList(4, zone_); 2758 this->NewPropertyList(4, zone_);
2750 ExpressionT constructor = this->EmptyExpression(); 2759 ExpressionT constructor = this->EmptyExpression();
2760 bool has_seen_constructor = false;
2751 2761
2752 Expect(Token::LBRACE, CHECK_OK); 2762 Expect(Token::LBRACE, CHECK_OK);
2753 while (peek() != Token::RBRACE) { 2763 while (peek() != Token::RBRACE) {
2754 if (Check(Token::SEMICOLON)) continue; 2764 if (Check(Token::SEMICOLON)) continue;
2755 if (fni_ != NULL) fni_->Enter(); 2765 if (fni_ != NULL) fni_->Enter();
2756
2757 const bool in_class = true; 2766 const bool in_class = true;
2758 const bool is_static = false; 2767 const bool is_static = false;
2759 ObjectLiteralPropertyT property = 2768 bool old_has_seen_constructor = has_seen_constructor;
2760 this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); 2769 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2770 NULL, in_class, is_static, &has_seen_constructor, CHECK_OK);
2761 2771
2762 if (this->IsConstructorProperty(property)) { 2772 if (has_seen_constructor != old_has_seen_constructor) {
2763 constructor = this->GetPropertyValue(property); 2773 constructor = this->GetPropertyValue(property);
2764 } else { 2774 } else {
2765 properties->Add(property, zone()); 2775 properties->Add(property, zone());
2766 } 2776 }
2767 2777
2768 if (fni_ != NULL) { 2778 if (fni_ != NULL) {
2769 fni_->Infer(); 2779 fni_->Infer();
2770 fni_->Leave(); 2780 fni_->Leave();
2771 } 2781 }
2772 } 2782 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 DCHECK(IsAccessorAccessorConflict(old_type, type)); 2841 DCHECK(IsAccessorAccessorConflict(old_type, type));
2832 // Both accessors of the same type. 2842 // Both accessors of the same type.
2833 parser()->ReportMessage("accessor_get_set"); 2843 parser()->ReportMessage("accessor_get_set");
2834 } 2844 }
2835 *ok = false; 2845 *ok = false;
2836 } 2846 }
2837 } 2847 }
2838 } } // v8::internal 2848 } } // v8::internal
2839 2849
2840 #endif // V8_PREPARSER_H 2850 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/messages.js ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698