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

Side by Side Diff: src/preparser.h

Issue 795573005: ES6 computed property names (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years 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
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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 // Parses an identifier and determines whether or not it is 'get' or 'set'. 490 // Parses an identifier and determines whether or not it is 'get' or 'set'.
484 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, 491 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get,
485 bool* is_set, 492 bool* is_set,
486 bool* ok); 493 bool* ok);
487 494
488 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); 495 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok);
489 496
490 ExpressionT ParsePrimaryExpression(bool* ok); 497 ExpressionT ParsePrimaryExpression(bool* ok);
491 ExpressionT ParseExpression(bool accept_IN, bool* ok); 498 ExpressionT ParseExpression(bool accept_IN, bool* ok);
492 ExpressionT ParseArrayLiteral(bool* ok); 499 ExpressionT ParseArrayLiteral(bool* ok);
493 IdentifierT ParsePropertyName(bool* is_get, bool* is_set, bool* is_static, 500 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
501 bool* is_static, bool* is_computed_name,
494 bool* ok); 502 bool* ok);
495 ExpressionT ParseObjectLiteral(bool* ok); 503 ExpressionT ParseObjectLiteral(bool* ok);
496 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker, 504 ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker,
497 bool in_class, bool is_static, 505 bool in_class, bool is_static,
506 bool* is_computed_name,
498 bool* has_seen_constructor, 507 bool* has_seen_constructor,
499 bool* ok); 508 bool* ok);
500 typename Traits::Type::ExpressionList ParseArguments(bool* ok); 509 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
501 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); 510 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
502 ExpressionT ParseYieldExpression(bool* ok); 511 ExpressionT ParseYieldExpression(bool* ok);
503 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 512 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
504 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 513 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
505 ExpressionT ParseUnaryExpression(bool* ok); 514 ExpressionT ParseUnaryExpression(bool* ok);
506 ExpressionT ParsePostfixExpression(bool* ok); 515 ExpressionT ParsePostfixExpression(bool* ok);
507 ExpressionT ParseLeftHandSideExpression(bool* ok); 516 ExpressionT ParseLeftHandSideExpression(bool* ok);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 600
592 private: 601 private:
593 Scanner* scanner_; 602 Scanner* scanner_;
594 bool stack_overflow_; 603 bool stack_overflow_;
595 604
596 bool allow_lazy_; 605 bool allow_lazy_;
597 bool allow_natives_; 606 bool allow_natives_;
598 bool allow_harmony_arrow_functions_; 607 bool allow_harmony_arrow_functions_;
599 bool allow_harmony_object_literals_; 608 bool allow_harmony_object_literals_;
600 bool allow_harmony_sloppy_; 609 bool allow_harmony_sloppy_;
610 bool allow_harmony_computed_property_names_;
601 611
602 typename Traits::Type::Zone* zone_; // Only used by Parser. 612 typename Traits::Type::Zone* zone_; // Only used by Parser.
603 }; 613 };
604 614
605 615
606 class PreParserIdentifier { 616 class PreParserIdentifier {
607 public: 617 public:
608 PreParserIdentifier() : type_(kUnknownIdentifier) {} 618 PreParserIdentifier() : type_(kUnknownIdentifier) {}
609 static PreParserIdentifier Default() { 619 static PreParserIdentifier Default() {
610 return PreParserIdentifier(kUnknownIdentifier); 620 return PreParserIdentifier(kUnknownIdentifier);
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 int literal_index, 1022 int literal_index,
1013 int pos) { 1023 int pos) {
1014 return PreParserExpression::Default(); 1024 return PreParserExpression::Default();
1015 } 1025 }
1016 PreParserExpression NewArrayLiteral(PreParserExpressionList values, 1026 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
1017 int literal_index, 1027 int literal_index,
1018 int pos) { 1028 int pos) {
1019 return PreParserExpression::Default(); 1029 return PreParserExpression::Default();
1020 } 1030 }
1021 PreParserExpression NewObjectLiteralProperty(bool is_getter, 1031 PreParserExpression NewObjectLiteralProperty(bool is_getter,
1032 PreParserExpression key,
1022 PreParserExpression value, 1033 PreParserExpression value,
1023 int pos, bool is_static) { 1034 int pos, bool is_static,
1035 bool is_computed_name) {
1024 return PreParserExpression::Default(); 1036 return PreParserExpression::Default();
1025 } 1037 }
1026 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, 1038 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
1027 PreParserExpression value, 1039 PreParserExpression value,
1028 bool is_static) { 1040 bool is_static,
1041 bool is_computed_name) {
1029 return PreParserExpression::Default(); 1042 return PreParserExpression::Default();
1030 } 1043 }
1031 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, 1044 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
1032 int literal_index, 1045 int literal_index,
1033 int boilerplate_properties, 1046 int boilerplate_properties,
1034 bool has_function, 1047 bool has_function,
1035 int pos) { 1048 int pos) {
1036 return PreParserExpression::Default(); 1049 return PreParserExpression::Default();
1037 } 1050 }
1038 PreParserExpression NewVariableProxy(void* variable) { 1051 PreParserExpression NewVariableProxy(void* variable) {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 static PreParserExpression GetPropertyValue(PreParserExpression property) { 1217 static PreParserExpression GetPropertyValue(PreParserExpression property) {
1205 return PreParserExpression::Default(); 1218 return PreParserExpression::Default();
1206 } 1219 }
1207 1220
1208 // Functions for encapsulating the differences between parsing and preparsing; 1221 // Functions for encapsulating the differences between parsing and preparsing;
1209 // operations interleaved with the recursive descent. 1222 // operations interleaved with the recursive descent.
1210 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 1223 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
1211 // PreParser should not use FuncNameInferrer. 1224 // PreParser should not use FuncNameInferrer.
1212 UNREACHABLE(); 1225 UNREACHABLE();
1213 } 1226 }
1227 static void PushLiteralName(FuncNameInferrer* fni,
1228 PreParserExpression expression) {
1229 // PreParser should not use FuncNameInferrer.
1230 UNREACHABLE();
1231 }
1214 static void PushPropertyName(FuncNameInferrer* fni, 1232 static void PushPropertyName(FuncNameInferrer* fni,
1215 PreParserExpression expression) { 1233 PreParserExpression expression) {
1216 // PreParser should not use FuncNameInferrer. 1234 // PreParser should not use FuncNameInferrer.
1217 UNREACHABLE(); 1235 UNREACHABLE();
1218 } 1236 }
1237 static void PushVariableName(FuncNameInferrer* fni, PreParserIdentifier id) {
1238 // PreParser should not use FuncNameInferrer.
1239 UNREACHABLE();
1240 }
1219 static void InferFunctionName(FuncNameInferrer* fni, 1241 static void InferFunctionName(FuncNameInferrer* fni,
1220 PreParserExpression expression) { 1242 PreParserExpression expression) {
1221 // PreParser should not use FuncNameInferrer. 1243 // PreParser should not use FuncNameInferrer.
1222 UNREACHABLE(); 1244 UNREACHABLE();
1223 } 1245 }
1224 1246
1225 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 1247 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
1226 PreParserScope* scope, PreParserExpression property, bool* has_function) { 1248 PreParserScope* scope, PreParserExpression property, bool* has_function) {
1227 } 1249 }
1228 1250
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 break; 1830 break;
1809 1831
1810 case Token::IDENTIFIER: 1832 case Token::IDENTIFIER:
1811 case Token::LET: 1833 case Token::LET:
1812 case Token::STATIC: 1834 case Token::STATIC:
1813 case Token::YIELD: 1835 case Token::YIELD:
1814 case Token::FUTURE_STRICT_RESERVED_WORD: { 1836 case Token::FUTURE_STRICT_RESERVED_WORD: {
1815 // Using eval or arguments in this context is OK even in strict mode. 1837 // Using eval or arguments in this context is OK even in strict mode.
1816 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1838 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1817 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); 1839 result = this->ExpressionFromIdentifier(name, pos, scope_, factory());
1840 if (fni_ != NULL) this->PushVariableName(fni_, name);
1818 break; 1841 break;
1819 } 1842 }
1820 1843
1821 case Token::STRING: { 1844 case Token::STRING: {
1822 Consume(Token::STRING); 1845 Consume(Token::STRING);
1823 result = this->ExpressionFromString(pos, scanner(), factory()); 1846 result = this->ExpressionFromString(pos, scanner(), factory());
1847 if (fni_ != NULL) this->PushLiteralName(fni_, result);
1824 break; 1848 break;
1825 } 1849 }
1826 1850
1827 case Token::ASSIGN_DIV: 1851 case Token::ASSIGN_DIV:
1828 result = this->ParseRegExpLiteral(true, CHECK_OK); 1852 result = this->ParseRegExpLiteral(true, CHECK_OK);
1829 break; 1853 break;
1830 1854
1831 case Token::DIV: 1855 case Token::DIV:
1832 result = this->ParseRegExpLiteral(false, CHECK_OK); 1856 result = this->ParseRegExpLiteral(false, CHECK_OK);
1833 break; 1857 break;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 Expect(Token::RBRACK, CHECK_OK); 1972 Expect(Token::RBRACK, CHECK_OK);
1949 1973
1950 // Update the scope information before the pre-parsing bailout. 1974 // Update the scope information before the pre-parsing bailout.
1951 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1975 int literal_index = function_state_->NextMaterializedLiteralIndex();
1952 1976
1953 return factory()->NewArrayLiteral(values, literal_index, pos); 1977 return factory()->NewArrayLiteral(values, literal_index, pos);
1954 } 1978 }
1955 1979
1956 1980
1957 template <class Traits> 1981 template <class Traits>
1958 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParsePropertyName( 1982 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
1959 bool* is_get, bool* is_set, bool* is_static, bool* ok) { 1983 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
1960 Token::Value next = peek(); 1984 bool* is_computed_name, bool* ok) {
1961 switch (next) { 1985 Token::Value token = peek();
1986 int pos = peek_position();
1987
1988 // For non computed property names we normalize the name a bit:
1989 //
1990 // "12" -> 12
1991 // 12.3 -> "12.3"
1992 // 12.30 -> "12.3"
1993 // identifier -> "identifier"
1994 //
1995 // This is important because we use the property name as a key in a hash
1996 // table when we computed constant properties.
1997 switch (token) {
1962 case Token::STRING: 1998 case Token::STRING:
1963 Consume(Token::STRING); 1999 Consume(Token::STRING);
1964 return this->GetSymbol(scanner_); 2000 *name = this->GetSymbol(scanner());
2001 break;
2002
1965 case Token::NUMBER: 2003 case Token::NUMBER:
1966 Consume(Token::NUMBER); 2004 Consume(Token::NUMBER);
1967 return this->GetNumberAsSymbol(scanner_); 2005 *name = this->GetNumberAsSymbol(scanner());
2006 break;
2007
2008 case Token::LBRACK:
2009 if (allow_harmony_computed_property_names_) {
2010 *is_computed_name = true;
2011 Consume(Token::LBRACK);
2012 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2013 Consume(Token::RBRACK);
2014 return expression;
2015 }
2016
2017 // Fall through.
1968 case Token::STATIC: 2018 case Token::STATIC:
1969 *is_static = true; 2019 *is_static = true;
1970 // Fall through. 2020
2021 // Fall through.
1971 default: 2022 default:
1972 return ParseIdentifierNameOrGetOrSet(is_get, is_set, ok); 2023 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
2024 break;
1973 } 2025 }
1974 UNREACHABLE(); 2026
1975 return this->EmptyIdentifier(); 2027 uint32_t index;
2028 return this->IsArrayIndex(*name, &index)
2029 ? factory()->NewNumberLiteral(index, pos)
2030 : factory()->NewStringLiteral(*name, pos);
1976 } 2031 }
1977 2032
1978 2033
1979 template <class Traits> 2034 template <class Traits>
1980 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase< 2035 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
1981 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker, 2036 Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker,
1982 bool in_class, bool is_static, 2037 bool in_class, bool is_static,
2038 bool* is_computed_name,
1983 bool* has_seen_constructor, bool* ok) { 2039 bool* has_seen_constructor, bool* ok) {
1984 DCHECK(!in_class || is_static || has_seen_constructor != NULL); 2040 DCHECK(!in_class || is_static || has_seen_constructor != NULL);
1985 ExpressionT value = this->EmptyExpression(); 2041 ExpressionT value = this->EmptyExpression();
2042 IdentifierT name = this->EmptyIdentifier();
1986 bool is_get = false; 2043 bool is_get = false;
1987 bool is_set = false; 2044 bool is_set = false;
1988 bool name_is_static = false; 2045 bool name_is_static = false;
1989 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); 2046 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
1990 2047
1991 Token::Value name_token = peek(); 2048 Token::Value name_token = peek();
1992 int next_pos = peek_position(); 2049 int next_pos = peek_position();
1993 IdentifierT name = 2050 ExpressionT name_expression = ParsePropertyName(
1994 ParsePropertyName(&is_get, &is_set, &name_is_static, 2051 &name, &is_get, &is_set, &name_is_static, is_computed_name,
1995 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2052 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1996 2053
1997 if (fni_ != NULL) this->PushLiteralName(fni_, name); 2054 if (!*is_computed_name && fni_ != NULL) {
arv (Not doing code reviews) 2014/12/10 23:38:13 if (fni_ != NULL) { since name is empty string fo
arv (Not doing code reviews) 2014/12/11 23:10:33 This one is needed.
2055 this->PushLiteralName(fni_, name);
2056 }
1998 2057
1999 if (!in_class && !is_generator && peek() == Token::COLON) { 2058 if (!in_class && !is_generator && peek() == Token::COLON) {
2000 // PropertyDefinition : PropertyName ':' AssignmentExpression 2059 // PropertyDefinition : PropertyName ':' AssignmentExpression
2001 if (checker != NULL) { 2060 if (!*is_computed_name && checker != NULL) {
arv (Not doing code reviews) 2014/12/10 23:38:13 maybe same here... need to check
arv (Not doing code reviews) 2014/12/11 23:10:33 This one is needed too.
2002 checker->CheckProperty(name_token, kValueProperty, 2061 checker->CheckProperty(name_token, kValueProperty,
2003 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2062 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2004 } 2063 }
2005 Consume(Token::COLON); 2064 Consume(Token::COLON);
2006 value = this->ParseAssignmentExpression( 2065 value = this->ParseAssignmentExpression(
2007 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2066 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2008 2067
2009 } else if (is_generator || 2068 } else if (is_generator ||
2010 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { 2069 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
2011 // Concise Method 2070 // Concise Method
(...skipping 17 matching lines...) Expand all
2029 if (*has_seen_constructor) { 2088 if (*has_seen_constructor) {
2030 ReportMessageAt(scanner()->location(), "duplicate_constructor"); 2089 ReportMessageAt(scanner()->location(), "duplicate_constructor");
2031 *ok = false; 2090 *ok = false;
2032 return this->EmptyObjectLiteralProperty(); 2091 return this->EmptyObjectLiteralProperty();
2033 } 2092 }
2034 2093
2035 *has_seen_constructor = true; 2094 *has_seen_constructor = true;
2036 kind = FunctionKind::kNormalFunction; 2095 kind = FunctionKind::kNormalFunction;
2037 } 2096 }
2038 2097
2039 if (checker != NULL) { 2098 if (!*is_computed_name && checker != NULL) {
2040 checker->CheckProperty(name_token, kValueProperty, 2099 checker->CheckProperty(name_token, kValueProperty,
2041 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2100 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2042 } 2101 }
2043 2102
2044 value = this->ParseFunctionLiteral( 2103 value = this->ParseFunctionLiteral(
2045 name, scanner()->location(), 2104 name, scanner()->location(),
2046 false, // reserved words are allowed here 2105 false, // reserved words are allowed here
2047 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 2106 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2048 FunctionLiteral::NORMAL_ARITY, 2107 FunctionLiteral::NORMAL_ARITY,
2049 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2108 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2050 2109
2051 } else if (in_class && name_is_static && !is_static) { 2110 } else if (in_class && name_is_static && !is_static) {
2052 // static MethodDefinition 2111 // static MethodDefinition
2053 return ParsePropertyDefinition(checker, true, true, NULL, ok); 2112 return ParsePropertyDefinition(checker, true, true, is_computed_name, NULL,
2113 ok);
2054 2114
2055 } else if (is_get || is_set) { 2115 } else if (is_get || is_set) {
2056 // Accessor 2116 // Accessor
2117 name = this->EmptyIdentifier();
2057 bool dont_care = false; 2118 bool dont_care = false;
2058 name_token = peek(); 2119 name_token = peek();
2059 name = ParsePropertyName(&dont_care, &dont_care, &dont_care, 2120
2060 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2121 name_expression = ParsePropertyName(
2122 &name, &dont_care, &dont_care, &dont_care, is_computed_name,
2123 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2061 2124
2062 // Validate the property. 2125 // Validate the property.
2063 if (is_static && this->IsPrototype(name)) { 2126 if (is_static && !*is_computed_name && this->IsPrototype(name)) {
arv (Not doing code reviews) 2014/12/11 23:10:34 this one is not needed because IsPrototype will be
2064 ReportMessageAt(scanner()->location(), "static_prototype"); 2127 ReportMessageAt(scanner()->location(), "static_prototype");
2065 *ok = false; 2128 *ok = false;
2066 return this->EmptyObjectLiteralProperty(); 2129 return this->EmptyObjectLiteralProperty();
2067 } else if (in_class && !is_static && this->IsConstructor(name)) { 2130 } else if (in_class && !is_static && this->IsConstructor(name)) {
2068 ReportMessageAt(scanner()->location(), "constructor_special_method"); 2131 ReportMessageAt(scanner()->location(), "constructor_special_method");
2069 *ok = false; 2132 *ok = false;
2070 return this->EmptyObjectLiteralProperty(); 2133 return this->EmptyObjectLiteralProperty();
2071 } 2134 }
2072 if (checker != NULL) { 2135 if (!*is_computed_name && checker != NULL) {
2073 checker->CheckProperty(name_token, 2136 checker->CheckProperty(name_token,
2074 is_get ? kGetterProperty : kSetterProperty, 2137 is_get ? kGetterProperty : kSetterProperty,
2075 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2138 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2076 } 2139 }
2077 2140
2078 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 2141 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
2079 name, scanner()->location(), 2142 name, scanner()->location(),
2080 false, // reserved words are allowed here 2143 false, // reserved words are allowed here
2081 FunctionKind::kNormalFunction, RelocInfo::kNoPosition, 2144 FunctionKind::kNormalFunction, RelocInfo::kNoPosition,
2082 FunctionLiteral::ANONYMOUS_EXPRESSION, 2145 FunctionLiteral::ANONYMOUS_EXPRESSION,
2083 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, 2146 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY,
2084 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2147 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2085 return factory()->NewObjectLiteralProperty(is_get, value, next_pos, 2148
2086 is_static); 2149 return factory()->NewObjectLiteralProperty(
2150 is_get, name_expression, value, next_pos, is_static, *is_computed_name);
2087 2151
2088 } else if (!in_class && allow_harmony_object_literals_ && 2152 } else if (!in_class && allow_harmony_object_literals_ &&
2089 Token::IsIdentifier(name_token, strict_mode(), 2153 Token::IsIdentifier(name_token, strict_mode(),
2090 this->is_generator())) { 2154 this->is_generator())) {
2091 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); 2155 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory());
2092 2156
2093 } else { 2157 } else {
2094 Token::Value next = Next(); 2158 Token::Value next = Next();
2095 ReportUnexpectedToken(next); 2159 ReportUnexpectedToken(next);
2096 *ok = false; 2160 *ok = false;
2097 return this->EmptyObjectLiteralProperty(); 2161 return this->EmptyObjectLiteralProperty();
2098 } 2162 }
2099 2163
2100 uint32_t index; 2164 return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
2101 LiteralT key = this->IsArrayIndex(name, &index) 2165 *is_computed_name);
2102 ? factory()->NewNumberLiteral(index, next_pos)
2103 : factory()->NewStringLiteral(name, next_pos);
2104
2105 return factory()->NewObjectLiteralProperty(key, value, is_static);
2106 } 2166 }
2107 2167
2108 2168
2109 template <class Traits> 2169 template <class Traits>
2110 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( 2170 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2111 bool* ok) { 2171 bool* ok) {
2112 // ObjectLiteral :: 2172 // ObjectLiteral ::
2113 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2173 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2114 2174
2115 int pos = peek_position(); 2175 int pos = peek_position();
2116 typename Traits::Type::PropertyList properties = 2176 typename Traits::Type::PropertyList properties =
2117 this->NewPropertyList(4, zone_); 2177 this->NewPropertyList(4, zone_);
2118 int number_of_boilerplate_properties = 0; 2178 int number_of_boilerplate_properties = 0;
2119 bool has_function = false; 2179 bool has_function = false;
2180 bool has_computed_names = false;
2120 2181
2121 ObjectLiteralChecker checker(this, strict_mode()); 2182 ObjectLiteralChecker checker(this, strict_mode());
2122 2183
2123 Expect(Token::LBRACE, CHECK_OK); 2184 Expect(Token::LBRACE, CHECK_OK);
2124 2185
2125 while (peek() != Token::RBRACE) { 2186 while (peek() != Token::RBRACE) {
2126 if (fni_ != NULL) fni_->Enter(); 2187 if (fni_ != NULL) fni_->Enter();
2127 2188
2128 const bool in_class = false; 2189 const bool in_class = false;
2129 const bool is_static = false; 2190 const bool is_static = false;
2191 bool is_computed_name = false;
2130 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( 2192 ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
2131 &checker, in_class, is_static, NULL, CHECK_OK); 2193 &checker, in_class, is_static, &is_computed_name, NULL, CHECK_OK);
2194
2195 if (is_computed_name) {
2196 has_computed_names = true;
2197 }
2132 2198
2133 // Mark top-level object literals that contain function literals and 2199 // Mark top-level object literals that contain function literals and
2134 // pretenure the literal so it can be added as a constant function 2200 // pretenure the literal so it can be added as a constant function
2135 // property. (Parser only.) 2201 // property. (Parser only.)
2136 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, 2202 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property,
2137 &has_function); 2203 &has_function);
2138 2204
2139 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 2205 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2140 if (this->IsBoilerplateProperty(property)) { 2206 if (!has_computed_names && this->IsBoilerplateProperty(property)) {
2141 number_of_boilerplate_properties++; 2207 number_of_boilerplate_properties++;
2142 } 2208 }
2143 properties->Add(property, zone()); 2209 properties->Add(property, zone());
2144 2210
2145 if (peek() != Token::RBRACE) { 2211 if (peek() != Token::RBRACE) {
2146 // Need {} because of the CHECK_OK macro. 2212 // Need {} because of the CHECK_OK macro.
2147 Expect(Token::COMMA, CHECK_OK); 2213 Expect(Token::COMMA, CHECK_OK);
2148 } 2214 }
2149 2215
2150 if (fni_ != NULL) { 2216 if (fni_ != NULL) {
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 DCHECK(IsAccessorAccessorConflict(old_type, type)); 2988 DCHECK(IsAccessorAccessorConflict(old_type, type));
2923 // Both accessors of the same type. 2989 // Both accessors of the same type.
2924 parser()->ReportMessage("accessor_get_set"); 2990 parser()->ReportMessage("accessor_get_set");
2925 } 2991 }
2926 *ok = false; 2992 *ok = false;
2927 } 2993 }
2928 } 2994 }
2929 } } // v8::internal 2995 } } // v8::internal
2930 2996
2931 #endif // V8_PREPARSER_H 2997 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698