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

Side by Side Diff: src/preparser.h

Issue 798243004: ES6 computed property names (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Disable test on windows Created 5 years, 11 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/parser.cc ('k') | src/preparser.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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 log_(log), 80 log_(log),
81 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 81 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
82 stack_limit_(stack_limit), 82 stack_limit_(stack_limit),
83 scanner_(scanner), 83 scanner_(scanner),
84 stack_overflow_(false), 84 stack_overflow_(false),
85 allow_lazy_(false), 85 allow_lazy_(false),
86 allow_natives_(false), 86 allow_natives_(false),
87 allow_harmony_arrow_functions_(false), 87 allow_harmony_arrow_functions_(false),
88 allow_harmony_object_literals_(false), 88 allow_harmony_object_literals_(false),
89 allow_harmony_sloppy_(false), 89 allow_harmony_sloppy_(false),
90 allow_harmony_computed_property_names_(false),
90 zone_(zone) {} 91 zone_(zone) {}
91 92
92 // Getters that indicate whether certain syntactical constructs are 93 // Getters that indicate whether certain syntactical constructs are
93 // allowed to be parsed by this instance of the parser. 94 // allowed to be parsed by this instance of the parser.
94 bool allow_lazy() const { return allow_lazy_; } 95 bool allow_lazy() const { return allow_lazy_; }
95 bool allow_natives() const { return allow_natives_; } 96 bool allow_natives() const { return allow_natives_; }
96 bool allow_harmony_arrow_functions() const { 97 bool allow_harmony_arrow_functions() const {
97 return allow_harmony_arrow_functions_; 98 return allow_harmony_arrow_functions_;
98 } 99 }
99 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } 100 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); }
100 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 101 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
101 bool allow_harmony_numeric_literals() const { 102 bool allow_harmony_numeric_literals() const {
102 return scanner()->HarmonyNumericLiterals(); 103 return scanner()->HarmonyNumericLiterals();
103 } 104 }
104 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } 105 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); }
105 bool allow_harmony_object_literals() const { 106 bool allow_harmony_object_literals() const {
106 return allow_harmony_object_literals_; 107 return allow_harmony_object_literals_;
107 } 108 }
108 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } 109 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); }
109 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } 110 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; }
110 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } 111 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
112 bool allow_harmony_computed_property_names() const {
113 return allow_harmony_computed_property_names_;
114 }
111 115
112 // Setters that determine whether certain syntactical constructs are 116 // Setters that determine whether certain syntactical constructs are
113 // allowed to be parsed by this instance of the parser. 117 // allowed to be parsed by this instance of the parser.
114 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 118 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
115 void set_allow_natives(bool allow) { allow_natives_ = allow; } 119 void set_allow_natives(bool allow) { allow_natives_ = allow; }
116 void set_allow_harmony_arrow_functions(bool allow) { 120 void set_allow_harmony_arrow_functions(bool allow) {
117 allow_harmony_arrow_functions_ = allow; 121 allow_harmony_arrow_functions_ = allow;
118 } 122 }
119 void set_allow_harmony_modules(bool allow) { 123 void set_allow_harmony_modules(bool allow) {
120 scanner()->SetHarmonyModules(allow); 124 scanner()->SetHarmonyModules(allow);
(...skipping 12 matching lines...) Expand all
133 } 137 }
134 void set_allow_harmony_templates(bool allow) { 138 void set_allow_harmony_templates(bool allow) {
135 scanner()->SetHarmonyTemplates(allow); 139 scanner()->SetHarmonyTemplates(allow);
136 } 140 }
137 void set_allow_harmony_sloppy(bool allow) { 141 void set_allow_harmony_sloppy(bool allow) {
138 allow_harmony_sloppy_ = allow; 142 allow_harmony_sloppy_ = allow;
139 } 143 }
140 void set_allow_harmony_unicode(bool allow) { 144 void set_allow_harmony_unicode(bool allow) {
141 scanner()->SetHarmonyUnicode(allow); 145 scanner()->SetHarmonyUnicode(allow);
142 } 146 }
147 void set_allow_harmony_computed_property_names(bool allow) {
148 allow_harmony_computed_property_names_ = allow;
149 }
143 150
144 protected: 151 protected:
145 enum AllowEvalOrArgumentsAsIdentifier { 152 enum AllowEvalOrArgumentsAsIdentifier {
146 kAllowEvalOrArguments, 153 kAllowEvalOrArguments,
147 kDontAllowEvalOrArguments 154 kDontAllowEvalOrArguments
148 }; 155 };
149 156
150 enum Mode { 157 enum Mode {
151 PARSE_LAZILY, 158 PARSE_LAZILY,
152 PARSE_EAGERLY 159 PARSE_EAGERLY
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 // Parses an identifier and determines whether or not it is 'get' or 'set'. 499 // Parses an identifier and determines whether or not it is 'get' or 'set'.
493 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, 500 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
494 bool* is_set, 501 bool* is_set,
495 bool* ok); 502 bool* ok);
496 503
497 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); 504 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
498 505
499 ExpressionT ParsePrimaryExpression(bool* ok); 506 ExpressionT ParsePrimaryExpression(bool* ok);
500 ExpressionT ParseExpression(bool accept_IN, bool* ok); 507 ExpressionT ParseExpression(bool accept_IN, bool* ok);
501 ExpressionT ParseArrayLiteral(bool* ok); 508 ExpressionT ParseArrayLiteral(bool* ok);
502 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static, 509 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
510 bool* is_static, bool* is_computed_name,
503 bool* ok); 511 bool* ok);
504 ExpressionT ParseObjectLiteral(bool* ok); 512 ExpressionT ParseObjectLiteral(bool* ok);
505 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, 513 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker,
506 bool in_class, bool is_static, 514 bool in_class, bool is_static,
515 bool* is_computed_name,
507 bool* has_seen_constructor, 516 bool* has_seen_constructor,
508 bool* ok); 517 bool* ok);
509 typename Traits::Type::ExpressionList ParseArguments(bool* ok); 518 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
510 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); 519 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
511 ExpressionT ParseYieldExpression(bool* ok); 520 ExpressionT ParseYieldExpression(bool* ok);
512 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 521 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
513 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 522 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
514 ExpressionT ParseUnaryExpression(bool* ok); 523 ExpressionT ParseUnaryExpression(bool* ok);
515 ExpressionT ParsePostfixExpression(bool* ok); 524 ExpressionT ParsePostfixExpression(bool* ok);
516 ExpressionT ParseLeftHandSideExpression(bool* ok); 525 ExpressionT ParseLeftHandSideExpression(bool* ok);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 609
601 private: 610 private:
602 Scanner* scanner_; 611 Scanner* scanner_;
603 bool stack_overflow_; 612 bool stack_overflow_;
604 613
605 bool allow_lazy_; 614 bool allow_lazy_;
606 bool allow_natives_; 615 bool allow_natives_;
607 bool allow_harmony_arrow_functions_; 616 bool allow_harmony_arrow_functions_;
608 bool allow_harmony_object_literals_; 617 bool allow_harmony_object_literals_;
609 bool allow_harmony_sloppy_; 618 bool allow_harmony_sloppy_;
619 bool allow_harmony_computed_property_names_;
610 620
611 typename Traits::Type::Zone* zone_; // Only used by Parser. 621 typename Traits::Type::Zone* zone_; // Only used by Parser.
612 }; 622 };
613 623
614 624
615 class PreParserIdentifier { 625 class PreParserIdentifier {
616 public: 626 public:
617 PreParserIdentifier() : type_(kUnknownIdentifier) {} 627 PreParserIdentifier() : type_(kUnknownIdentifier) {}
618 static PreParserIdentifier Default() { 628 static PreParserIdentifier Default() {
619 return PreParserIdentifier(kUnknownIdentifier); 629 return PreParserIdentifier(kUnknownIdentifier);
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 int literal_index, 1043 int literal_index,
1034 int pos) { 1044 int pos) {
1035 return PreParserExpression::Default(); 1045 return PreParserExpression::Default();
1036 } 1046 }
1037 PreParserExpression NewArrayLiteral(PreParserExpressionList values, 1047 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1038 int literal_index, 1048 int literal_index,
1039 int pos) { 1049 int pos) {
1040 return PreParserExpression::Default(); 1050 return PreParserExpression::Default();
1041 } 1051 }
1042 PreParserExpression NewObjectLiteralProperty(bool is_getter, 1052 PreParserExpression NewObjectLiteralProperty(bool is_getter,
1053 PreParserExpression key,
1043 PreParserExpression value, 1054 PreParserExpression value,
1044 int pos, bool is_static) { 1055 int pos, bool is_static,
1056 bool is_computed_name) {
1045 return PreParserExpression::Default(); 1057 return PreParserExpression::Default();
1046 } 1058 }
1047 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, 1059 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1048 PreParserExpression value, 1060 PreParserExpression value,
1049 bool is_static) { 1061 bool is_static,
1062 bool is_computed_name) {
1050 return PreParserExpression::Default(); 1063 return PreParserExpression::Default();
1051 } 1064 }
1052 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, 1065 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
1053 int literal_index, 1066 int literal_index,
1054 int boilerplate_properties, 1067 int boilerplate_properties,
1055 bool has_function, 1068 bool has_function,
1056 int pos) { 1069 int pos) {
1057 return PreParserExpression::Default(); 1070 return PreParserExpression::Default();
1058 } 1071 }
1059 PreParserExpression NewVariableProxy(void* variable) { 1072 PreParserExpression NewVariableProxy(void* variable) {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 static PreParserExpression GetPropertyValue(PreParserExpression property) { 1238 static PreParserExpression GetPropertyValue(PreParserExpression property) {
1226 return PreParserExpression::Default(); 1239 return PreParserExpression::Default();
1227 } 1240 }
1228 1241
1229 // Functions for encapsulating the differences between parsing and preparsing; 1242 // Functions for encapsulating the differences between parsing and preparsing;
1230 // operations interleaved with the recursive descent. 1243 // operations interleaved with the recursive descent.
1231 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 1244 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1232 // PreParser should not use FuncNameInferrer. 1245 // PreParser should not use FuncNameInferrer.
1233 UNREACHABLE(); 1246 UNREACHABLE();
1234 } 1247 }
1248
1235 static void PushPropertyName(FuncNameInferrer* fni, 1249 static void PushPropertyName(FuncNameInferrer* fni,
1236 PreParserExpression expression) { 1250 PreParserExpression expression) {
1237 // PreParser should not use FuncNameInferrer. 1251 // PreParser should not use FuncNameInferrer.
1238 UNREACHABLE(); 1252 UNREACHABLE();
1239 } 1253 }
1254
1240 static void InferFunctionName(FuncNameInferrer* fni, 1255 static void InferFunctionName(FuncNameInferrer* fni,
1241 PreParserExpression expression) { 1256 PreParserExpression expression) {
1242 // PreParser should not use FuncNameInferrer. 1257 // PreParser should not use FuncNameInferrer.
1243 UNREACHABLE(); 1258 UNREACHABLE();
1244 } 1259 }
1245 1260
1246 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 1261 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
1247 PreParserScope* scope, PreParserExpression property, bool* has_function) { 1262 PreParserScope* scope, PreParserExpression property, bool* has_function) {
1248 } 1263 }
1249 1264
(...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after
1990 Expect(Token::RBRACK, CHECK_OK); 2005 Expect(Token::RBRACK, CHECK_OK);
1991 2006
1992 // Update the scope information before the pre-parsing bailout. 2007 // Update the scope information before the pre-parsing bailout.
1993 int literal_index = function_state_->NextMaterializedLiteralIndex(); 2008 int literal_index = function_state_->NextMaterializedLiteralIndex();
1994 2009
1995 return factory()->NewArrayLiteral(values, literal_index, pos); 2010 return factory()->NewArrayLiteral(values, literal_index, pos);
1996 } 2011 }
1997 2012
1998 2013
1999 template <class Traits> 2014 template <class Traits>
2000 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName( 2015 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
2001 bool* is_get, bool* is_set, bool* is_static, bool* ok) { 2016 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
2002 Token::Value next = peek(); 2017 bool* is_computed_name, bool* ok) {
2003 switch (next) { 2018 Token::Value token = peek();
2019 int pos = peek_position();
2020
2021 // For non computed property names we normalize the name a bit:
2022 //
2023 // "12" -> 12
2024 // 12.3 -> "12.3"
2025 // 12.30 -> "12.3"
2026 // identifier -> "identifier"
2027 //
2028 // This is important because we use the property name as a key in a hash
2029 // table when we compute constant properties.
2030 switch (token) {
2004 case Token::STRING: 2031 case Token::STRING:
2005 Consume(Token::STRING); 2032 Consume(Token::STRING);
2006 return this->GetSymbol(scanner_); 2033 *name = this->GetSymbol(scanner());
2034 break;
2035
2007 case Token::NUMBER: 2036 case Token::NUMBER:
2008 Consume(Token::NUMBER); 2037 Consume(Token::NUMBER);
2009 return this->GetNumberAsSymbol(scanner_); 2038 *name = this->GetNumberAsSymbol(scanner());
2039 break;
2040
2041 case Token::LBRACK:
2042 if (allow_harmony_computed_property_names_) {
2043 *is_computed_name = true;
2044 Consume(Token::LBRACK);
2045 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2046 Expect(Token::RBRACK, CHECK_OK);
2047 return expression;
2048 }
2049
2050 // Fall through.
2010 case Token::STATIC: 2051 case Token::STATIC:
2011 *is_static = true; 2052 *is_static = true;
2012 // Fall through. 2053
2054 // Fall through.
2013 default: 2055 default:
2014 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); 2056 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2057 break;
2015 } 2058 }
2016 UNREACHABLE(); 2059
2017 return this->EmptyIdentifier(); 2060 uint32_t index;
2061 return this->IsArrayIndex(*name, &index)
2062 ? factory()->NewNumberLiteral(index, pos)
2063 : factory()->NewStringLiteral(*name, pos);
2018 } 2064 }
2019 2065
2020 2066
2021 template <class Traits> 2067 template <class Traits>
2022 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< 2068 typename ParserBase<Traits>::ObjectLiteralPropertyT
2023 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, 2069 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker,
2024 bool in_class, bool is_static, 2070 bool in_class, bool is_static,
2025 bool* has_seen_constructor, bool* ok) { 2071 bool* is_computed_name,
2072 bool* has_seen_constructor,
2073 bool* ok) {
2026 DCHECK(!in_class || is_static || has_seen_constructor != NULL); 2074 DCHECK(!in_class || is_static || has_seen_constructor != NULL);
2027 ExpressionT value = this->EmptyExpression(); 2075 ExpressionT value = this->EmptyExpression();
2076 IdentifierT name = this->EmptyIdentifier();
2028 bool is_get = false; 2077 bool is_get = false;
2029 bool is_set = false; 2078 bool is_set = false;
2030 bool name_is_static = false; 2079 bool name_is_static = false;
2031 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); 2080 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
2032 2081
2033 Token::Value name_token = peek(); 2082 Token::Value name_token = peek();
2034 int next_pos = peek_position(); 2083 int next_pos = peek_position();
2035 IdentifierT name = 2084 ExpressionT name_expression = ParsePropertyName(
2036 ParsePropertyName(&is_get, &is_set, &name_is_static, 2085 &name, &is_get, &is_set, &name_is_static, is_computed_name,
2037 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2086 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2038 2087
2039 if (fni_ != NULL) this->PushLiteralName(fni_, name); 2088 if (fni_ != NULL && !*is_computed_name) {
2089 this->PushLiteralName(fni_, name);
2090 }
2040 2091
2041 if (!in_class && !is_generator && peek() == Token::COLON) { 2092 if (!in_class && !is_generator && peek() == Token::COLON) {
2042 // PropertyDefinition : PropertyName ':' AssignmentExpression 2093 // PropertyDefinition : PropertyName ':' AssignmentExpression
2043 if (checker != NULL) { 2094 if (!*is_computed_name && checker != NULL) {
2044 checker->CheckProperty(name_token, kValueProperty, 2095 checker->CheckProperty(name_token, kValueProperty,
2045 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2096 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2046 } 2097 }
2047 Consume(Token::COLON); 2098 Consume(Token::COLON);
2048 value = this->ParseAssignmentExpression( 2099 value = this->ParseAssignmentExpression(
2049 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2100 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2050 2101
2051 } else if (is_generator || 2102 } else if (is_generator ||
2052 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { 2103 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
2053 // Concise Method 2104 // Concise Method
(...skipping 17 matching lines...) Expand all
2071 if (*has_seen_constructor) { 2122 if (*has_seen_constructor) {
2072 ReportMessageAt(scanner()->location(), "duplicate_constructor"); 2123 ReportMessageAt(scanner()->location(), "duplicate_constructor");
2073 *ok = false; 2124 *ok = false;
2074 return this->EmptyObjectLiteralProperty(); 2125 return this->EmptyObjectLiteralProperty();
2075 } 2126 }
2076 2127
2077 *has_seen_constructor = true; 2128 *has_seen_constructor = true;
2078 kind = FunctionKind::kNormalFunction; 2129 kind = FunctionKind::kNormalFunction;
2079 } 2130 }
2080 2131
2081 if (checker != NULL) { 2132 if (!*is_computed_name && checker != NULL) {
2082 checker->CheckProperty(name_token, kValueProperty, 2133 checker->CheckProperty(name_token, kValueProperty,
2083 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2134 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2084 } 2135 }
2085 2136
2086 value = this->ParseFunctionLiteral( 2137 value = this->ParseFunctionLiteral(
2087 name, scanner()->location(), 2138 name, scanner()->location(),
2088 false, // reserved words are allowed here 2139 false, // reserved words are allowed here
2089 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 2140 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2090 FunctionLiteral::NORMAL_ARITY, 2141 FunctionLiteral::NORMAL_ARITY,
2091 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2142 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2092 2143
2093 } else if (in_class && name_is_static && !is_static) { 2144 } else if (in_class && name_is_static && !is_static) {
2094 // static MethodDefinition 2145 // static MethodDefinition
2095 return ParsePropertyDefinition(checker, true, true, NULL, ok); 2146 return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL,
2147 ok);
2096 2148
2097 } else if (is_get || is_set) { 2149 } else if (is_get || is_set) {
2098 // Accessor 2150 // Accessor
2151 name = this->EmptyIdentifier();
2099 bool dont_care = false; 2152 bool dont_care = false;
2100 name_token = peek(); 2153 name_token = peek();
2101 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, 2154
2102 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2155 name_expression = ParsePropertyName(
2156 &name, &dont_care, &dont_care, &dont_care, is_computed_name,
2157 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2103 2158
2104 // Validate the property. 2159 // Validate the property.
2105 if (is_static && this->IsPrototype(name)) { 2160 if (is_static && this->IsPrototype(name)) {
2106 ReportMessageAt(scanner()->location(), "static_prototype"); 2161 ReportMessageAt(scanner()->location(), "static_prototype");
2107 *ok = false; 2162 *ok = false;
2108 return this->EmptyObjectLiteralProperty(); 2163 return this->EmptyObjectLiteralProperty();
2109 } else if (in_class && !is_static && this->IsConstructor(name)) { 2164 } else if (in_class && !is_static && this->IsConstructor(name)) {
2110 ReportMessageAt(scanner()->location(), "constructor_special_method"); 2165 ReportMessageAt(scanner()->location(), "constructor_special_method");
2111 *ok = false; 2166 *ok = false;
2112 return this->EmptyObjectLiteralProperty(); 2167 return this->EmptyObjectLiteralProperty();
2113 } 2168 }
2114 if (checker != NULL) { 2169 if (!*is_computed_name && checker != NULL) {
2115 checker->CheckProperty(name_token, 2170 checker->CheckProperty(name_token,
2116 is_get ? kGetterProperty : kSetterProperty, 2171 is_get ? kGetterProperty : kSetterProperty,
2117 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2172 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2118 } 2173 }
2119 2174
2120 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2175 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2121 name, scanner()->location(), 2176 name, scanner()->location(),
2122 false, // reserved words are allowed here 2177 false, // reserved words are allowed here
2123 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, 2178 FunctionKind::kNormalFunction, RelocInfo::kNoPosition,
2124 FunctionLiteral::ANONYMOUS_EXPRESSION, 2179 FunctionLiteral::ANONYMOUS_EXPRESSION,
2125 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, 2180 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2126 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2181 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2127 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, 2182
2128 is_static); 2183 // Make sure the name expression is a string since we need a Name for
2184 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2185 // statically we can skip the extra runtime check.
2186 if (!*is_computed_name) {
2187 name_expression =
2188 factory()->NewStringLiteral(name, name_expression->position());
2189 }
2190
2191 return factory()->NewObjectLiteralProperty(
2192 is_get, name_expression, value, next_pos, is_static, *is_computed_name);
2129 2193
2130 } else if (!in_class && allow_harmony_object_literals_ && 2194 } else if (!in_class && allow_harmony_object_literals_ &&
2131 Token::IsIdentifier(name_token, strict_mode(), 2195 Token::IsIdentifier(name_token, strict_mode(),
2132 this->is_generator())) { 2196 this->is_generator())) {
2133 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); 2197 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory());
2134 2198
2135 } else { 2199 } else {
2136 Token::Value next = Next(); 2200 Token::Value next = Next();
2137 ReportUnexpectedToken(next); 2201 ReportUnexpectedToken(next);
2138 *ok = false; 2202 *ok = false;
2139 return this->EmptyObjectLiteralProperty(); 2203 return this->EmptyObjectLiteralProperty();
2140 } 2204 }
2141 2205
2142 uint32_t index; 2206 return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
2143 LiteralT key = this->IsArrayIndex(name, &index) 2207 *is_computed_name);
2144 ? factory()->NewNumberLiteral(index, next_pos)
2145 : factory()->NewStringLiteral(name, next_pos);
2146
2147 return factory()->NewObjectLiteralProperty(key, value, is_static);
2148 } 2208 }
2149 2209
2150 2210
2151 template <class Traits> 2211 template <class Traits>
2152 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( 2212 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2153 bool* ok) { 2213 bool* ok) {
2154 // ObjectLiteral :: 2214 // ObjectLiteral ::
2155 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2215 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2156 2216
2157 int pos = peek_position(); 2217 int pos = peek_position();
2158 typename Traits::Type::PropertyList properties = 2218 typename Traits::Type::PropertyList properties =
2159 this->NewPropertyList(4, zone_); 2219 this->NewPropertyList(4, zone_);
2160 int number_of_boilerplate_properties = 0; 2220 int number_of_boilerplate_properties = 0;
2161 bool has_function = false; 2221 bool has_function = false;
2222 bool has_computed_names = false;
2162 2223
2163 ObjectLiteralChecker checker(this, strict_mode()); 2224 ObjectLiteralChecker checker(this, strict_mode());
2164 2225
2165 Expect(Token::LBRACE, CHECK_OK); 2226 Expect(Token::LBRACE, CHECK_OK);
2166 2227
2167 while (peek() != Token::RBRACE) { 2228 while (peek() != Token::RBRACE) {
2168 if (fni_ != NULL) fni_->Enter(); 2229 if (fni_ != NULL) fni_->Enter();
2169 2230
2170 const bool in_class = false; 2231 const bool in_class = false;
2171 const bool is_static = false; 2232 const bool is_static = false;
2233 bool is_computed_name = false;
2172 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( 2234 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2173 &checker, in_class, is_static, NULL, CHECK_OK); 2235 &checker, in_class, is_static, &is_computed_name, NULL, CHECK_OK);
2236
2237 if (is_computed_name) {
2238 has_computed_names = true;
2239 }
2174 2240
2175 // Mark top-level object literals that contain function literals and 2241 // Mark top-level object literals that contain function literals and
2176 // pretenure the literal so it can be added as a constant function 2242 // pretenure the literal so it can be added as a constant function
2177 // property. (Parser only.) 2243 // property. (Parser only.)
2178 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, 2244 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2179 &has_function); 2245 &has_function);
2180 2246
2181 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 2247 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2182 if (this->IsBoilerplateProperty(property)) { 2248 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2183 number_of_boilerplate_properties++; 2249 number_of_boilerplate_properties++;
2184 } 2250 }
2185 properties->Add(property, zone()); 2251 properties->Add(property, zone());
2186 2252
2187 if (peek() != Token::RBRACE) { 2253 if (peek() != Token::RBRACE) {
2188 // Need {} because of the CHECK_OK macro. 2254 // Need {} because of the CHECK_OK macro.
2189 Expect(Token::COMMA, CHECK_OK); 2255 Expect(Token::COMMA, CHECK_OK);
2190 } 2256 }
2191 2257
2192 if (fni_ != NULL) { 2258 if (fni_ != NULL) {
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
2968 DCHECK(IsAccessorAccessorConflict(old_type, type)); 3034 DCHECK(IsAccessorAccessorConflict(old_type, type));
2969 // Both accessors of the same type. 3035 // Both accessors of the same type.
2970 parser()->ReportMessage("accessor_get_set"); 3036 parser()->ReportMessage("accessor_get_set");
2971 } 3037 }
2972 *ok = false; 3038 *ok = false;
2973 } 3039 }
2974 } 3040 }
2975 } } // v8::internal 3041 } } // v8::internal
2976 3042
2977 #endif // V8_PREPARSER_H 3043 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698