Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
| 7 | 7 |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 stack_overflow_(false), | 210 stack_overflow_(false), |
| 211 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), | 211 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), |
| 212 function_literal_id_(0), | 212 function_literal_id_(0), |
| 213 allow_natives_(false), | 213 allow_natives_(false), |
| 214 allow_tailcalls_(false), | 214 allow_tailcalls_(false), |
| 215 allow_harmony_do_expressions_(false), | 215 allow_harmony_do_expressions_(false), |
| 216 allow_harmony_function_sent_(false), | 216 allow_harmony_function_sent_(false), |
| 217 allow_harmony_async_await_(false), | 217 allow_harmony_async_await_(false), |
| 218 allow_harmony_restrictive_generators_(false), | 218 allow_harmony_restrictive_generators_(false), |
| 219 allow_harmony_trailing_commas_(false), | 219 allow_harmony_trailing_commas_(false), |
| 220 allow_harmony_class_fields_(false) {} | 220 allow_harmony_class_fields_(false), |
| 221 allow_harmony_object_spread_(false) {} | |
| 221 | 222 |
| 222 #define ALLOW_ACCESSORS(name) \ | 223 #define ALLOW_ACCESSORS(name) \ |
| 223 bool allow_##name() const { return allow_##name##_; } \ | 224 bool allow_##name() const { return allow_##name##_; } \ |
| 224 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 225 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
| 225 | 226 |
| 226 ALLOW_ACCESSORS(natives); | 227 ALLOW_ACCESSORS(natives); |
| 227 ALLOW_ACCESSORS(tailcalls); | 228 ALLOW_ACCESSORS(tailcalls); |
| 228 ALLOW_ACCESSORS(harmony_do_expressions); | 229 ALLOW_ACCESSORS(harmony_do_expressions); |
| 229 ALLOW_ACCESSORS(harmony_function_sent); | 230 ALLOW_ACCESSORS(harmony_function_sent); |
| 230 ALLOW_ACCESSORS(harmony_async_await); | 231 ALLOW_ACCESSORS(harmony_async_await); |
| 231 ALLOW_ACCESSORS(harmony_restrictive_generators); | 232 ALLOW_ACCESSORS(harmony_restrictive_generators); |
| 232 ALLOW_ACCESSORS(harmony_trailing_commas); | 233 ALLOW_ACCESSORS(harmony_trailing_commas); |
| 233 ALLOW_ACCESSORS(harmony_class_fields); | 234 ALLOW_ACCESSORS(harmony_class_fields); |
| 235 ALLOW_ACCESSORS(harmony_object_spread); | |
| 234 | 236 |
| 235 #undef ALLOW_ACCESSORS | 237 #undef ALLOW_ACCESSORS |
| 236 | 238 |
| 237 uintptr_t stack_limit() const { return stack_limit_; } | 239 uintptr_t stack_limit() const { return stack_limit_; } |
| 238 | 240 |
| 239 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 241 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
| 240 | 242 |
| 241 void set_default_eager_compile_hint( | 243 void set_default_eager_compile_hint( |
| 242 FunctionLiteral::EagerCompileHint eager_compile_hint) { | 244 FunctionLiteral::EagerCompileHint eager_compile_hint) { |
| 243 default_eager_compile_hint_ = eager_compile_hint; | 245 default_eager_compile_hint_ = eager_compile_hint; |
| (...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1142 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok); | 1144 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok); |
| 1143 | 1145 |
| 1144 ExpressionT ParseArrayLiteral(bool* ok); | 1146 ExpressionT ParseArrayLiteral(bool* ok); |
| 1145 | 1147 |
| 1146 enum class PropertyKind { | 1148 enum class PropertyKind { |
| 1147 kAccessorProperty, | 1149 kAccessorProperty, |
| 1148 kValueProperty, | 1150 kValueProperty, |
| 1149 kShorthandProperty, | 1151 kShorthandProperty, |
| 1150 kMethodProperty, | 1152 kMethodProperty, |
| 1151 kClassField, | 1153 kClassField, |
| 1154 kSpreadProperty, | |
| 1152 kNotSet | 1155 kNotSet |
| 1153 }; | 1156 }; |
| 1154 | 1157 |
| 1155 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); | 1158 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); |
| 1156 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, | 1159 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, |
| 1157 bool* is_generator, bool* is_get, bool* is_set, | 1160 bool* is_generator, bool* is_get, bool* is_set, |
| 1158 bool* is_async, bool* is_computed_name, | 1161 bool* is_async, bool* is_computed_name, |
| 1159 bool* ok); | 1162 bool* ok); |
| 1160 ExpressionT ParseObjectLiteral(bool* ok); | 1163 ExpressionT ParseObjectLiteral(bool* ok); |
| 1161 ClassLiteralPropertyT ParseClassPropertyDefinition( | 1164 ClassLiteralPropertyT ParseClassPropertyDefinition( |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1448 int function_literal_id_; | 1451 int function_literal_id_; |
| 1449 | 1452 |
| 1450 bool allow_natives_; | 1453 bool allow_natives_; |
| 1451 bool allow_tailcalls_; | 1454 bool allow_tailcalls_; |
| 1452 bool allow_harmony_do_expressions_; | 1455 bool allow_harmony_do_expressions_; |
| 1453 bool allow_harmony_function_sent_; | 1456 bool allow_harmony_function_sent_; |
| 1454 bool allow_harmony_async_await_; | 1457 bool allow_harmony_async_await_; |
| 1455 bool allow_harmony_restrictive_generators_; | 1458 bool allow_harmony_restrictive_generators_; |
| 1456 bool allow_harmony_trailing_commas_; | 1459 bool allow_harmony_trailing_commas_; |
| 1457 bool allow_harmony_class_fields_; | 1460 bool allow_harmony_class_fields_; |
| 1461 bool allow_harmony_object_spread_; | |
| 1458 | 1462 |
| 1459 friend class DiscardableZoneScope; | 1463 friend class DiscardableZoneScope; |
| 1460 }; | 1464 }; |
| 1461 | 1465 |
| 1462 template <typename Impl> | 1466 template <typename Impl> |
| 1463 ParserBase<Impl>::FunctionState::FunctionState( | 1467 ParserBase<Impl>::FunctionState::FunctionState( |
| 1464 FunctionState** function_state_stack, ScopeState** scope_stack, | 1468 FunctionState** function_state_stack, ScopeState** scope_stack, |
| 1465 DeclarationScope* scope) | 1469 DeclarationScope* scope) |
| 1466 : ScopeState(scope_stack, scope), | 1470 : ScopeState(scope_stack, scope), |
| 1467 next_materialized_literal_index_(0), | 1471 next_materialized_literal_index_(0), |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2101 *is_computed_name = true; | 2105 *is_computed_name = true; |
| 2102 Consume(Token::LBRACK); | 2106 Consume(Token::LBRACK); |
| 2103 ExpressionClassifier computed_name_classifier(this); | 2107 ExpressionClassifier computed_name_classifier(this); |
| 2104 expression = ParseAssignmentExpression(true, CHECK_OK); | 2108 expression = ParseAssignmentExpression(true, CHECK_OK); |
| 2105 impl()->RewriteNonPattern(CHECK_OK); | 2109 impl()->RewriteNonPattern(CHECK_OK); |
| 2106 impl()->AccumulateFormalParameterContainmentErrors(); | 2110 impl()->AccumulateFormalParameterContainmentErrors(); |
| 2107 Expect(Token::RBRACK, CHECK_OK); | 2111 Expect(Token::RBRACK, CHECK_OK); |
| 2108 break; | 2112 break; |
| 2109 } | 2113 } |
| 2110 | 2114 |
| 2115 case Token::ELLIPSIS: { | |
| 2116 if (allow_harmony_object_spread()) { | |
| 2117 // TODO(gsathya): Implement destructuring/rest | |
| 2118 BindingPatternUnexpectedToken(); | |
|
adamk
2016/12/29 00:48:45
I think you'll need to disallow this in assignment
gsathya
2016/12/29 06:40:56
Done.
adamk
2016/12/29 18:32:45
You can get both at once with
classifier()->Recor
gsathya
2017/01/05 22:18:35
Done.
| |
| 2119 | |
| 2120 *name = impl()->EmptyIdentifier(); | |
| 2121 Consume(Token::ELLIPSIS); | |
| 2122 ExpressionClassifier spread_classifier(this); | |
| 2123 expression = ParseAssignmentExpression(false, CHECK_OK); | |
|
adamk
2016/12/29 00:48:45
Don't you want to accept "in"? Please add a test,
gsathya
2016/12/29 06:40:56
Done.
| |
| 2124 impl()->RewriteNonPattern(CHECK_OK); | |
| 2125 impl()->AccumulateFormalParameterContainmentErrors(); | |
| 2126 *kind = PropertyKind::kSpreadProperty; | |
| 2127 return expression; | |
| 2128 } | |
| 2129 } | |
| 2130 | |
| 2111 default: | 2131 default: |
| 2112 *name = ParseIdentifierName(CHECK_OK); | 2132 *name = ParseIdentifierName(CHECK_OK); |
| 2113 break; | 2133 break; |
| 2114 } | 2134 } |
| 2115 | 2135 |
| 2116 if (*kind == PropertyKind::kNotSet) { | 2136 if (*kind == PropertyKind::kNotSet) { |
| 2117 SetPropertyKindFromToken(peek(), kind); | 2137 SetPropertyKindFromToken(peek(), kind); |
| 2118 } | 2138 } |
| 2119 | 2139 |
| 2120 if (*is_computed_name) { | 2140 if (*is_computed_name) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2261 if (!*is_computed_name) { | 2281 if (!*is_computed_name) { |
| 2262 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2282 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
| 2263 } | 2283 } |
| 2264 | 2284 |
| 2265 *property_kind = | 2285 *property_kind = |
| 2266 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; | 2286 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; |
| 2267 return factory()->NewClassLiteralProperty(name_expression, value, | 2287 return factory()->NewClassLiteralProperty(name_expression, value, |
| 2268 *property_kind, *is_static, | 2288 *property_kind, *is_static, |
| 2269 *is_computed_name); | 2289 *is_computed_name); |
| 2270 } | 2290 } |
| 2291 case PropertyKind::kSpreadProperty: | |
| 2292 UNREACHABLE(); | |
| 2271 } | 2293 } |
| 2272 UNREACHABLE(); | 2294 UNREACHABLE(); |
| 2273 return impl()->EmptyClassLiteralProperty(); | 2295 return impl()->EmptyClassLiteralProperty(); |
| 2274 } | 2296 } |
| 2275 | 2297 |
| 2276 template <typename Impl> | 2298 template <typename Impl> |
| 2277 typename ParserBase<Impl>::FunctionLiteralT | 2299 typename ParserBase<Impl>::FunctionLiteralT |
| 2278 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, | 2300 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, |
| 2279 bool* ok) { | 2301 bool* ok) { |
| 2280 // Makes a concise method which evaluates and returns the initialized value | 2302 // Makes a concise method which evaluates and returns the initialized value |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2322 IdentifierT name = impl()->EmptyIdentifier(); | 2344 IdentifierT name = impl()->EmptyIdentifier(); |
| 2323 Token::Value name_token = peek(); | 2345 Token::Value name_token = peek(); |
| 2324 int next_beg_pos = scanner()->peek_location().beg_pos; | 2346 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 2325 int next_end_pos = scanner()->peek_location().end_pos; | 2347 int next_end_pos = scanner()->peek_location().end_pos; |
| 2326 | 2348 |
| 2327 ExpressionT name_expression = ParsePropertyName( | 2349 ExpressionT name_expression = ParsePropertyName( |
| 2328 &name, &kind, &is_generator, &is_get, &is_set, &is_async, | 2350 &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
| 2329 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2351 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2330 | 2352 |
| 2331 switch (kind) { | 2353 switch (kind) { |
| 2354 case PropertyKind::kSpreadProperty: { | |
| 2355 if (allow_harmony_object_spread()) { | |
|
adamk
2016/12/29 00:48:45
This can be a DCHECK, since ParsePropertyName shou
gsathya
2016/12/29 06:40:56
Done.
| |
| 2356 DCHECK(!is_get && !is_set && !is_generator && !is_async); | |
|
adamk
2016/12/29 00:48:45
you should add !*is_computed_name to this list.
gsathya
2016/12/29 06:40:56
Done.
| |
| 2357 DCHECK(name_token == Token::ELLIPSIS); | |
| 2358 | |
| 2359 *is_computed_name = true; | |
| 2360 *ok = true; | |
|
adamk
2016/12/29 00:48:45
No need to set *ok to true, that's how it starts.
gsathya
2016/12/29 06:40:56
Done.
| |
| 2361 | |
| 2362 return factory()->NewObjectLiteralProperty( | |
| 2363 impl()->GetLiteralTheHole(kNoSourcePosition), name_expression, | |
| 2364 ObjectLiteralProperty::SPREAD, true); | |
| 2365 } | |
| 2366 } | |
| 2367 | |
| 2332 case PropertyKind::kValueProperty: { | 2368 case PropertyKind::kValueProperty: { |
| 2333 DCHECK(!is_get && !is_set && !is_generator && !is_async); | 2369 DCHECK(!is_get && !is_set && !is_generator && !is_async); |
| 2334 | 2370 |
| 2335 if (!*is_computed_name) { | 2371 if (!*is_computed_name) { |
| 2336 checker->CheckDuplicateProto(name_token); | 2372 checker->CheckDuplicateProto(name_token); |
| 2337 } | 2373 } |
| 2338 Consume(Token::COLON); | 2374 Consume(Token::COLON); |
| 2339 int beg_pos = peek_position(); | 2375 int beg_pos = peek_position(); |
| 2340 ExpressionT value = ParseAssignmentExpression( | 2376 ExpressionT value = ParseAssignmentExpression( |
| 2341 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2377 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| (...skipping 3156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5498 has_seen_constructor_ = true; | 5534 has_seen_constructor_ = true; |
| 5499 return; | 5535 return; |
| 5500 } | 5536 } |
| 5501 } | 5537 } |
| 5502 | 5538 |
| 5503 | 5539 |
| 5504 } // namespace internal | 5540 } // namespace internal |
| 5505 } // namespace v8 | 5541 } // namespace v8 |
| 5506 | 5542 |
| 5507 #endif // V8_PARSING_PARSER_BASE_H | 5543 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |